@tencentcloud/sdk-mcp 1.7.7 → 1.7.9-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.md +7 -9
- package/index.js +8 -8
- package/knowledge/chunker.js +1 -0
- package/knowledge/doc-url-resolver.js +16 -9
- package/knowledge/embedding/build-vectors.js +92 -0
- package/knowledge/embedding/embed-model.js +41 -0
- package/knowledge/embedding/vector-augment.js +126 -0
- package/knowledge/embedding/vector-index.js +70 -0
- package/knowledge/frontmatter-meta.js +23 -0
- package/knowledge/path-meta.js +56 -0
- package/knowledge/search/exact-lookup.js +145 -16
- package/knowledge/search/filter-pool.js +77 -33
- package/knowledge/search/rank-profile.js +25 -0
- package/knowledge/search/requires-framework.js +4 -1
- package/knowledge/search/search-core.js +74 -13
- package/knowledge/search/search-knowledge.js +24 -34
- package/knowledge/search/search-pass.js +495 -169
- package/knowledge/search/url-row-scorer.js +24 -6
- package/package.json +3 -1
- package/resource/index/manifest.json +1 -1
- package/resource/index/vectors/index.json +4 -0
- package/resource/integration/callkit/preset/android/integration.md +0 -2
- package/resource/integration/callkit/preset/ios/integration.md +0 -2
- package/resource/integration/chat/preset/react/integration.md +9 -5
- package/resource/integration/chat/preset/uni-app/integration.md +4 -0
- package/resource/integration/chat/preset/vue/integration.md +10 -6
- package/resource/integration/livekit/preset/live/android/prepare-integration.md +0 -4
- package/resource/integration/livekit/preset/live/ios/prepare-integration.md +0 -4
- package/resource/integration/roomkit/preset/vue/integration.md +154 -208
- package/resource/knowledge/callkit/best-practice/android/video-chat-dating.md +0 -2
- package/resource/knowledge/callkit/core-sdk/android/answer-call.md +0 -2
- package/resource/knowledge/callkit/core-sdk/android/make-call.md +0 -2
- package/resource/knowledge/callkit/core-sdk/flutter/answer-call.md +0 -4
- package/resource/knowledge/callkit/core-sdk/flutter/make-call.md +0 -2
- package/resource/knowledge/callkit/core-sdk/flutter/offline-push.md +0 -2
- package/resource/knowledge/callkit/core-sdk/ios/answer-call.md +0 -2
- package/resource/knowledge/callkit/core-sdk/ios/make-call.md +0 -4
- package/resource/knowledge/callkit/core-sdk/ios/offline-push.md +0 -2
- package/resource/knowledge/callkit/core-sdk/uni-app/answer-call.md +0 -2
- package/resource/knowledge/callkit/core-sdk/uni-app/make-call.md +0 -2
- package/resource/knowledge/callkit/faq/ios.md +0 -2
- package/resource/knowledge/callkit/faq/uniapp-app.md +0 -2
- package/resource/knowledge/callkit/preset/miniprogram/integration.md +2 -3
- package/resource/knowledge/callkit/preset/miniprogram/uniapp-integration.md +0 -2
- package/resource/knowledge/chat/preset/ios-uikit/integration.md +0 -16
- package/resource/knowledge/chat/preset/react/h5/integration.md +16 -5
- package/resource/knowledge/chat/preset/vue/features/conversation-list.md +6 -3
- package/resource/knowledge/chat/preset/vue/h5/integration.md +7 -4
- package/resource/knowledge/iot/app/activate-service.md +95 -0
- package/resource/knowledge/iot/app/demo/android.md +93 -0
- package/resource/knowledge/iot/app/demo/ios.md +87 -0
- package/resource/knowledge/iot/app/demo/miniprogram.md +79 -0
- package/resource/knowledge/iot/app/device-binding.md +378 -0
- package/resource/knowledge/iot/app/device-sharing.md +414 -0
- package/resource/knowledge/iot/app/family-management.md +762 -0
- package/resource/knowledge/iot/app/integration/android.md +328 -0
- package/resource/knowledge/iot/app/integration/harmonyos.md +326 -0
- package/resource/knowledge/iot/app/integration/ios.md +351 -0
- package/resource/knowledge/iot/app/integration/miniprogram.md +268 -0
- package/resource/knowledge/iot/app/monitor-playback.md +557 -0
- package/resource/knowledge/iot/app/remote-control.md +139 -0
- package/resource/knowledge/iot/app/video-call.md +559 -0
- package/resource/knowledge/iot/app/wechat-call/device-call-miniprogram.md +204 -0
- package/resource/knowledge/iot/app/wechat-call/miniprogram-call-device.md +193 -0
- package/resource/knowledge/iot/client-api/app/android/txiotcallsession.md +189 -0
- package/resource/knowledge/iot/client-api/app/android/txiotcloudstorage.md +77 -0
- package/resource/knowledge/iot/client-api/app/android/txiotdevicemanager.md +175 -0
- package/resource/knowledge/iot/client-api/app/android/txiotengine.md +172 -0
- package/resource/knowledge/iot/client-api/app/android/txiotenginedef.md +163 -0
- package/resource/knowledge/iot/client-api/app/android/txiotfamilymanager.md +146 -0
- package/resource/knowledge/iot/client-api/app/android/txiotmonitorsession.md +246 -0
- package/resource/knowledge/iot/client-api/app/harmonyos/txiotcallsession.md +191 -0
- package/resource/knowledge/iot/client-api/app/harmonyos/txiotcloudstorage.md +77 -0
- package/resource/knowledge/iot/client-api/app/harmonyos/txiotdevicemanager.md +183 -0
- package/resource/knowledge/iot/client-api/app/harmonyos/txiotengine.md +186 -0
- package/resource/knowledge/iot/client-api/app/harmonyos/txiotenginedef.md +164 -0
- package/resource/knowledge/iot/client-api/app/harmonyos/txiotfamilymanager.md +150 -0
- package/resource/knowledge/iot/client-api/app/harmonyos/txiotmonitorsession.md +252 -0
- package/resource/knowledge/iot/client-api/app/ios/txiotcallsession.md +199 -0
- package/resource/knowledge/iot/client-api/app/ios/txiotcloudstorage.md +76 -0
- package/resource/knowledge/iot/client-api/app/ios/txiotdevicemanager.md +173 -0
- package/resource/knowledge/iot/client-api/app/ios/txiotengine.md +173 -0
- package/resource/knowledge/iot/client-api/app/ios/txiotenginedef.md +171 -0
- package/resource/knowledge/iot/client-api/app/ios/txiotfamilymanager.md +146 -0
- package/resource/knowledge/iot/client-api/app/ios/txiotmonitorsession.md +250 -0
- package/resource/knowledge/iot/client-api/app/miniprogram/txiotcallsession.md +180 -0
- package/resource/knowledge/iot/client-api/app/miniprogram/txiotcloudstorage.md +76 -0
- package/resource/knowledge/iot/client-api/app/miniprogram/txiotdevicemanager.md +281 -0
- package/resource/knowledge/iot/client-api/app/miniprogram/txiotengine.md +183 -0
- package/resource/knowledge/iot/client-api/app/miniprogram/txiotenginedef.md +152 -0
- package/resource/knowledge/iot/client-api/app/miniprogram/txiotfamilymanager.md +179 -0
- package/resource/knowledge/iot/client-api/app/miniprogram/txiotmonitorsession.md +226 -0
- package/resource/knowledge/iot/client-api/device/android-smart-device.md +813 -0
- package/resource/knowledge/iot/client-api/device/linux-rtos-device.md +2027 -0
- package/resource/knowledge/iot/device/activate-service.md +167 -0
- package/resource/knowledge/iot/device/ai-voice-chat/advanced-features/custom-agent.md +171 -0
- package/resource/knowledge/iot/device/ai-voice-chat/advanced-features/smart-device-control.md +721 -0
- package/resource/knowledge/iot/device/ai-voice-chat/integration-guide/android-smart-device.md +247 -0
- package/resource/knowledge/iot/device/ai-voice-chat/integration-guide/linux-rtos-device.md +368 -0
- package/resource/knowledge/iot/device/ai-voice-chat/overview.md +84 -0
- package/resource/knowledge/iot/device/cloud-storage.md +696 -0
- package/resource/knowledge/iot/device/data-model.md +972 -0
- package/resource/knowledge/iot/device/demo/android-smart-device.md +97 -0
- package/resource/knowledge/iot/device/demo/linux-rtos-device.md +106 -0
- package/resource/knowledge/iot/device/device-ota-upgrade.md +237 -0
- package/resource/knowledge/iot/device/dynamic-registration/android-smart-device.md +275 -0
- package/resource/knowledge/iot/device/dynamic-registration/linux-rtos-device.md +297 -0
- package/resource/knowledge/iot/device/login-and-register/android-smart-device.md +131 -0
- package/resource/knowledge/iot/device/login-and-register/linux-rtos-device.md +291 -0
- package/resource/knowledge/iot/device/monitor-pushing/android-smart-device.md +237 -0
- package/resource/knowledge/iot/device/monitor-pushing/linux-rtos-device.md +493 -0
- package/resource/knowledge/iot/device/video-call/android-smart-device.md +299 -0
- package/resource/knowledge/iot/device/video-call/linux-rtos-device.md +465 -0
- package/resource/knowledge/iot/device/wechat-call/android-smart-device.md +534 -0
- package/resource/knowledge/iot/device/wechat-call/linux-rtos-device.md +681 -0
- package/resource/knowledge/iot/kids-watch/overview.md +28 -0
- package/resource/knowledge/iot/security-camera/activate-service.md +74 -0
- package/resource/knowledge/iot/security-camera/monitor-playback/app-integration.md +302 -0
- package/resource/knowledge/iot/security-camera/monitor-playback/device-integration/android.md +237 -0
- package/resource/knowledge/iot/security-camera/monitor-playback/device-integration/linux-rtos.md +493 -0
- package/resource/knowledge/iot/security-camera/overview.md +31 -0
- package/resource/knowledge/iot/security-camera/ptz-control.md +153 -0
- package/resource/knowledge/iot/security-camera/recording-and-snapshot.md +182 -0
- package/resource/knowledge/iot/security-camera/voice-intercom.md +174 -0
- package/resource/knowledge/iot/smart-vision/serviceoverview.md +114 -0
- package/resource/knowledge/iot/voice-recorder/app-demo.md +99 -0
- package/resource/knowledge/iot/voice-recorder/device-demo.md +189 -0
- package/resource/knowledge/iot/voice-recorder/overview.md +64 -0
- package/resource/knowledge/livekit/core-sdk/features/android/base-beauty.md +0 -2
- package/resource/knowledge/livekit/core-sdk/features/android/gift.md +0 -4
- package/resource/knowledge/livekit/core-sdk/features/android/live-list.md +0 -2
- package/resource/knowledge/livekit/core-sdk/features/flutter/audio-effect.md +0 -2
- package/resource/knowledge/livekit/core-sdk/features/flutter/base-beauty.md +0 -2
- package/resource/knowledge/livekit/core-sdk/features/flutter/gift.md +0 -4
- package/resource/knowledge/livekit/core-sdk/features/ios/base-beauty.md +0 -2
- package/resource/knowledge/livekit/core-sdk/features/ios/gift.md +0 -4
- package/resource/knowledge/livekit/core-sdk/features/ios/live-list.md +0 -2
- package/resource/knowledge/livekit/core-sdk/features/uni-app/base-beauty.md +0 -2
- package/resource/knowledge/livekit/core-sdk/features/uni-app/gift.md +0 -4
- package/resource/knowledge/livekit/core-sdk/live/android/co-guest-interaction.md +0 -4
- package/resource/knowledge/livekit/core-sdk/live/android/host-interaction.md +0 -10
- package/resource/knowledge/livekit/core-sdk/live/android/integration.md +0 -2
- package/resource/knowledge/livekit/core-sdk/live/flutter/co-guest-interaction.md +0 -2
- package/resource/knowledge/livekit/core-sdk/live/flutter/host-interaction.md +0 -10
- package/resource/knowledge/livekit/core-sdk/live/flutter/integration.md +0 -2
- package/resource/knowledge/livekit/core-sdk/live/ios/co-guest-interaction.md +0 -4
- package/resource/knowledge/livekit/core-sdk/live/ios/host-interaction.md +0 -10
- package/resource/knowledge/livekit/core-sdk/live/ios/integration.md +0 -2
- package/resource/knowledge/livekit/core-sdk/live/uni-app/co-guest-interaction.md +0 -4
- package/resource/knowledge/livekit/core-sdk/live/uni-app/host-interaction.md +0 -4
- package/resource/knowledge/livekit/core-sdk/live/uni-app/integration.md +0 -2
- package/resource/knowledge/livekit/core-sdk/voice/android/co-guest-interaction.md +0 -2
- package/resource/knowledge/livekit/core-sdk/voice/android/host-interaction.md +0 -4
- package/resource/knowledge/livekit/core-sdk/voice/android/integration.md +0 -4
- package/resource/knowledge/livekit/core-sdk/voice/flutter/integration.md +0 -2
- package/resource/knowledge/livekit/core-sdk/voice/ios/co-guest-interaction.md +0 -2
- package/resource/knowledge/livekit/core-sdk/voice/ios/host-interaction.md +0 -4
- package/resource/knowledge/livekit/core-sdk/voice/ios/integration.md +0 -4
- package/resource/knowledge/livekit/core-sdk/voice/uni-app/co-guest-interaction.md +0 -2
- package/resource/knowledge/livekit/core-sdk/voice/uni-app/integration.md +0 -2
- package/resource/knowledge/livekit/faq/error-code.md +0 -2
- package/resource/knowledge/push/config/android/honor.md +16 -1
- package/resource/knowledge/push/config/android/huawei.md +20 -4
- package/resource/knowledge/push/config/android/meizu.md +19 -5
- package/resource/knowledge/push/config/android/vivo.md +20 -1
- package/resource/knowledge/push/config/donut.md +0 -2
- package/resource/knowledge/push/config/harmonyos.md +21 -5
- package/resource/knowledge/push/integration/android.md +0 -5
- package/resource/knowledge/push/integration/donut.md +0 -3
- package/resource/knowledge/push/integration/flutter.md +1 -4
- package/resource/knowledge/push/integration/harmonyos.md +0 -3
- package/resource/knowledge/push/integration/ios.md +0 -3
- package/resource/knowledge/push/integration/react-native.md +0 -5
- package/resource/knowledge/push/integration/uni-app.md +0 -3
- package/resource/knowledge/push/integration/unity.md +0 -3
- package/resource/knowledge/push/integration/unreal-engine.md +0 -3
- package/resource/knowledge/roomkit/core-sdk/android/call-user-to-room.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/android/room-participant-state.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/android/room-state.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/android/schedule-room.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/flutter/call-user-to-room.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/flutter/room-participant-state.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/flutter/room-state.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/flutter/schedule-room.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/ios/call-user-to-room.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/ios/room-participant-state.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/ios/room-state.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/ios/schedule-room.md +0 -2
- package/resource/knowledge/roomkit/core-sdk/vue/room-view.md +0 -3
- package/resource/knowledge/roomkit/preset/uniapp-app/integration.md +18 -14
- package/resource/knowledge/rtcengine/web/how_to_run_web_sdk_demo.md +0 -2
- package/resource/knowledge/rtcengine/web/plugin/23-advanced-support-detection.md +30 -0
- package/resource/knowledge/rtcengine/web/plugin/24-advanced-network-quality.md +0 -2
- package/resource/knowledge/rtcengine/web/plugin/31-advanced-plugins-overview.md +1 -1
- package/resource/knowledge/rtcengine/web/plugin/35-advanced-ai-denoiser.md +1 -1
- package/resource/knowledge/rtcengine/web/plugin/36-advanced-virtual-background.md +4 -0
- package/resource/knowledge/trtc/android/TRTCCloud.md +94 -85
- package/resource/knowledge/trtc/android/TRTCCloudDef.md +48 -46
- package/resource/knowledge/trtc/android/TRTCCloudListener.md +48 -48
- package/resource/knowledge/trtc/android/TXAudioEffectManager.md +18 -18
- package/resource/knowledge/trtc/android/TXDeviceManager.md +4 -4
- package/resource/knowledge/trtc/android/TXLiteAVCode.md +1 -0
- package/resource/knowledge/trtc/c++/ITRTCCloud.md +90 -90
- package/resource/knowledge/trtc/c++/ITXAudioEffectManager.md +18 -18
- package/resource/knowledge/trtc/c++/ITXDeviceManager.md +9 -9
- package/resource/knowledge/trtc/c++/TRTCCloudCallback.md +47 -47
- package/resource/knowledge/trtc/c++/TRTCTypeDef.md +47 -45
- package/resource/knowledge/trtc/c++/TXLiteAVCode.md +1 -0
- package/resource/knowledge/trtc/ios/TRTCCloud.md +93 -93
- package/resource/knowledge/trtc/ios/TRTCCloudDelegate.md +50 -50
- package/resource/knowledge/trtc/ios/TXAudioEffectManager.md +8 -8
- package/resource/knowledge/trtc/ios/TXDeviceManager.md +9 -9
- package/resource/knowledge/trtc/ios/TXLiteAVCode.md +1 -0
- package/resource/knowledge/trtc/ios/TXLiveSDKTypeDef.md +48 -46
- package/server-config.js +8 -9
- package/server.js +1 -1
- package/tools/common/finalize_answer.js +1 -1
- package/tools/common/present_framework_choice.js +1 -1
- package/tools/common/search_trtc_knowledge.js +22 -3
- package/tools/definitions/search_trtc_knowledge_def.js +3 -2
- package/utils/preflight-route.js +19 -2
- package/utils/report-cls-client.js +1 -1
- package/utils/report-es-client.js +1 -1
|
@@ -0,0 +1,721 @@
|
|
|
1
|
+
---
|
|
2
|
+
product: iot
|
|
3
|
+
framework:
|
|
4
|
+
- '*'
|
|
5
|
+
types:
|
|
6
|
+
- feature
|
|
7
|
+
retrievable_scope: always
|
|
8
|
+
feature_domain: device
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
借助智能体的**工具配置**能力,结合 [腾讯云物联网开发平台](https://cloud.tencent.com/document/product/1081/34726) 的 [物模型通信](https://cloud.tencent.com/document/product/1081/135031) 能力,可以实现设备的智能控制。
|
|
12
|
+
|
|
13
|
+
本文以电量查询、音量控制两个案例,分别介绍如何获取设备自身属性(电量查询)与修改设备属性(音量控制)。如果有这方面的业务需求,可以按照我们提供的实践案例来进行定制改造。
|
|
14
|
+
|
|
15
|
+
## 前置条件
|
|
16
|
+
1. 已经熟悉 自定义智能体 的相关配置和使用。
|
|
17
|
+
|
|
18
|
+
2. 已经熟悉 [物模型通信](https://cloud.tencent.com/document/product/1081/135031) 并跑通完整 Demo。
|
|
19
|
+
|
|
20
|
+
3. 已经跑通 AI 对话 [接入指引](https://cloud.tencent.com/document/product/1081/137894),能正常对话。
|
|
21
|
+
|
|
22
|
+
## 实践案例
|
|
23
|
+
|
|
24
|
+
### 案例一:查询设备电量
|
|
25
|
+
1. 在腾讯云物联网开发平台 [控制台](https://console.cloud.tencent.com/iotexplorer/v2) 产品详情页的功能定义页面,单击**新增功能**,定义一个电量查询行为。
|
|
26
|
+
|
|
27
|
+
2. 在控制台 **TWeTalk 智能体配置**页面,进入对应智能体的**工具配置**,单击**创建工具**:
|
|
28
|
+
|
|
29
|
+
|配置项|说明|
|
|
30
|
+
|---------|---------|
|
|
31
|
+
|工具类型|默认选择 **IoT 工具**。|
|
|
32
|
+
|工具名称|和定义行为中的标识符保持一致,当前为:**get_battery**。|
|
|
33
|
+
|工具描述|和定义行为中的描述保持一致,当前为:**获取设备当前电量**。|
|
|
34
|
+
|工具参数|当前只是获取设备属性,不涉及控制下发,该项留空,后续在控制音量案例中介绍。|
|
|
35
|
+
|输出参数|行为执行结果的数据项:**battery**(整型,当前电量百分比),需与物模型定义的输出参数保持一致。|
|
|
36
|
+
|
|
37
|
+
3. 在 [AI 对话的设备端 SDK](https://cloud.tencent.com/document/product/1081/137894) 集成 [物模型通信](https://cloud.tencent.com/document/product/1081/135031) 能力:
|
|
38
|
+
|
|
39
|
+
``` c
|
|
40
|
+
#include <stdbool.h>
|
|
41
|
+
#include <stdlib.h>
|
|
42
|
+
#include <string.h>
|
|
43
|
+
|
|
44
|
+
#include "tc_iot.h"
|
|
45
|
+
#include "tc_iot_aitalk.h"
|
|
46
|
+
#include "tc_iot_data_model.h"
|
|
47
|
+
|
|
48
|
+
/* 登录和开始对话均为异步操作,回调中记录结果,主流程据此继续或退出。 */
|
|
49
|
+
static volatile bool s_login_done = false;
|
|
50
|
+
static volatile bool s_start_done = false;
|
|
51
|
+
static volatile bool s_aitalk_error = false;
|
|
52
|
+
static volatile bool s_data_model_done = false;
|
|
53
|
+
static tc_iot_error_e s_login_result = TC_IOT_ERR_SUCCESS;
|
|
54
|
+
static tc_iot_error_e s_start_result = TC_IOT_ERR_SUCCESS;
|
|
55
|
+
|
|
56
|
+
static data_model_data_item_t s_action_output[1];
|
|
57
|
+
|
|
58
|
+
static void on_login(tc_iot_error_e error_code, const char *error_message) {
|
|
59
|
+
s_login_result = error_code;
|
|
60
|
+
s_login_done = true;
|
|
61
|
+
// 登录失败时,可在这里记录 error_message 并通知上层业务。
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static void on_start_speak(tc_iot_error_e error_code, const char *error_message) {
|
|
65
|
+
s_start_result = error_code;
|
|
66
|
+
s_start_done = true;
|
|
67
|
+
// 开始对话失败时,可在这里记录 error_message 并通知上层业务。
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static void on_receive_bot_audio(const tc_iot_audio_frame *frame, void *user_data) {
|
|
71
|
+
(void)user_data;
|
|
72
|
+
if (!frame || !frame->data || frame->data_size == 0) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// 这里收到的音频是经过解码后的 PCM 音频
|
|
76
|
+
// 将 frame->data 推送到具体的音频设备播放。
|
|
77
|
+
// 例如:调用芯片平台的扬声器播放、PCM 输出或音频框架接口。
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
static void on_receive_bot_text(const char *text, void *user_data) {
|
|
81
|
+
(void)user_data;
|
|
82
|
+
if (!text) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
// 将机器人回复文本显示到屏幕,或上传到您的业务服务。
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
static void on_receive_asr_text(const char *text, void *user_data) {
|
|
89
|
+
(void)user_data;
|
|
90
|
+
if (!text) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// 将用户语音识别结果显示到屏幕,或用于本地业务处理。
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
static void on_bot_state_changed(tc_iot_aitalk_bot_state_e old_state,
|
|
97
|
+
tc_iot_aitalk_bot_state_e new_state,
|
|
98
|
+
void *user_data) {
|
|
99
|
+
(void)old_state;
|
|
100
|
+
(void)user_data;
|
|
101
|
+
// 根据 new_state 更新设备指示灯、屏幕或其他交互状态。
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
static void on_aitalk_error(tc_iot_error_e error_code, const char *error_message,
|
|
105
|
+
void *user_data) {
|
|
106
|
+
(void)user_data;
|
|
107
|
+
s_aitalk_error = true;
|
|
108
|
+
// 记录 error_code 和 error_message,并停止或重试业务流程。
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/*
|
|
112
|
+
* 在平台麦克风的数据回调中调用本函数。
|
|
113
|
+
* data、size、codec 和 pts_ms 均来自当前平台的音频采集结果。
|
|
114
|
+
*/
|
|
115
|
+
static void on_mic_captured(const uint8_t *data, uint32_t size,
|
|
116
|
+
tc_iot_audio_codec_e codec, uint64_t pts_ms,
|
|
117
|
+
void *user_data) {
|
|
118
|
+
(void)user_data;
|
|
119
|
+
if (!data || size == 0) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
tc_iot_audio_frame frame = {0};
|
|
124
|
+
frame.codec = codec;
|
|
125
|
+
frame.sample_rate = TC_IOT_AUDIO_SAMPLE_RATE_16000;
|
|
126
|
+
frame.channels = TC_IOT_AUDIO_CHANNEL_MONO;
|
|
127
|
+
frame.frame_duration_ms = 20;
|
|
128
|
+
frame.data = (uint8_t *)data;
|
|
129
|
+
frame.data_size = size;
|
|
130
|
+
frame.pts_ms = pts_ms;
|
|
131
|
+
|
|
132
|
+
tc_iot_error_e rc = tc_iot_aitalk_send_audio(&frame);
|
|
133
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
134
|
+
// 记录发送失败原因;必要时停止采集或触发重连。
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ==================== 物模型通信 ====================
|
|
139
|
+
// 属性上报结果回调
|
|
140
|
+
static void on_report_property_result_cb(char *property_id, void *user_data,
|
|
141
|
+
data_model_report_result_t result_code) {
|
|
142
|
+
(void)user_data;
|
|
143
|
+
printf("[demo] report property result: id=%s, code=%d\n",
|
|
144
|
+
property_id ? property_id : "(null)", (int)result_code);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// 事件上报结果回调
|
|
148
|
+
static void on_report_event_result_cb(char *event_id, void *user_data,
|
|
149
|
+
data_model_report_result_t result_code) {
|
|
150
|
+
(void)user_data;
|
|
151
|
+
printf("[demo] report event result: id=%s, code=%d\n",
|
|
152
|
+
event_id ? event_id : "(null)", (int)result_code);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// 云端修改属性
|
|
156
|
+
static void on_receive_property_changed_cb(char *property_id,
|
|
157
|
+
tc_iot_data_model_property_t *data_model_property) {
|
|
158
|
+
if (!property_id || !data_model_property) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
data_model_data_item_t *item = &data_model_property->property;
|
|
162
|
+
printf("[demo] property changed: id=%s, type=%d\n", item->data_id, (int)item->data_type);
|
|
163
|
+
// 按 item->data_type 解析 item->data_value 并更新本地状态 ...
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// 云端下发行为
|
|
167
|
+
static int on_receive_new_action_cb(char *action_id,
|
|
168
|
+
tc_iot_data_model_action_t *data_model_action) {
|
|
169
|
+
if (!action_id || !data_model_action) {
|
|
170
|
+
return -1;
|
|
171
|
+
}
|
|
172
|
+
printf("[demo] receive new action: id=%s, input_num=%u\n", action_id,
|
|
173
|
+
(unsigned)data_model_action->action_input_data_num);
|
|
174
|
+
// 查询电量
|
|
175
|
+
if (!strcmp(action_id, "get_battery")) {
|
|
176
|
+
// 模拟电量,真实业务请接入真实电量百分比
|
|
177
|
+
static int battery = 58;
|
|
178
|
+
s_action_output[0].data_id = "battery";
|
|
179
|
+
s_action_output[0].data_type = DATA_MODEL_DATA_TYPE_INT;
|
|
180
|
+
s_action_output[0].data_value.value_int = battery--;
|
|
181
|
+
// 先填好数据再设置数量,避免出现数量与列表不一致的中间状态
|
|
182
|
+
data_model_action->action_output_data_num = 1;
|
|
183
|
+
data_model_action->action_output_data_list = s_action_output;
|
|
184
|
+
printf("[demo] current battery: %d\n", s_action_output[0].data_value.value_int);
|
|
185
|
+
}
|
|
186
|
+
return 0;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
int main(void) {
|
|
190
|
+
bool sdk_inited = false;
|
|
191
|
+
bool aitalk_inited = false;
|
|
192
|
+
bool speak_started = false;
|
|
193
|
+
bool conversation_completed = false;
|
|
194
|
+
tc_iot_error_e rc;
|
|
195
|
+
|
|
196
|
+
// 1. 配置并初始化 SDK。
|
|
197
|
+
tc_iot_config_s sdk_config = {0};
|
|
198
|
+
sdk_config.storage_path = "./";
|
|
199
|
+
sdk_config.log_level = TC_IOT_LOG_LEVEL_INFO;
|
|
200
|
+
rc = tc_iot_init(&sdk_config);
|
|
201
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
202
|
+
goto cleanup;
|
|
203
|
+
}
|
|
204
|
+
sdk_inited = true;
|
|
205
|
+
|
|
206
|
+
// 2. 从安全配置中读取设备三元组并登录平台。
|
|
207
|
+
tc_iot_device_info_s device_info = {0};
|
|
208
|
+
device_info.product_id = get_product_id();
|
|
209
|
+
device_info.device_id = get_device_name();
|
|
210
|
+
device_info.device_secret = get_device_secret();
|
|
211
|
+
device_info.region = "ap-guangzhou";
|
|
212
|
+
|
|
213
|
+
s_login_done = false;
|
|
214
|
+
rc = tc_iot_login(&device_info, on_login);
|
|
215
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
216
|
+
goto cleanup;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// 等待 on_login 回调或超时;休眠接口请替换为具体平台实现。
|
|
220
|
+
wait_until(&s_login_done, 30000);
|
|
221
|
+
if (!s_login_done || s_login_result != TC_IOT_ERR_SUCCESS) {
|
|
222
|
+
goto cleanup;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// 3. 初始化物模型
|
|
226
|
+
tc_iot_data_model_callback_t callback = {
|
|
227
|
+
.on_report_property_result_cb = on_report_property_result_cb,
|
|
228
|
+
.on_receive_property_changed_cb = on_receive_property_changed_cb,
|
|
229
|
+
.on_report_event_result_cb = on_report_event_result_cb,
|
|
230
|
+
.on_receive_new_action_cb = on_receive_new_action_cb,
|
|
231
|
+
};
|
|
232
|
+
rc = tc_iot_data_model_init(callback);
|
|
233
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
234
|
+
goto cleanup;
|
|
235
|
+
}
|
|
236
|
+
s_data_model_done = true;
|
|
237
|
+
|
|
238
|
+
// 4. 注册 AI 对话事件回调并初始化模块。
|
|
239
|
+
tc_iot_aitalk_observer_s observer = {0};
|
|
240
|
+
observer.on_receive_bot_audio = on_receive_bot_audio;
|
|
241
|
+
observer.on_receive_bot_text = on_receive_bot_text;
|
|
242
|
+
observer.on_receive_asr_text = on_receive_asr_text;
|
|
243
|
+
observer.on_bot_state_changed = on_bot_state_changed;
|
|
244
|
+
observer.on_error = on_aitalk_error;
|
|
245
|
+
|
|
246
|
+
tc_iot_aitalk_init_params_s init_params = {0};
|
|
247
|
+
// 根据实际情况配置 agent-id prompt_variables_json
|
|
248
|
+
// 根据实际采集参数设置编码、采样率和单帧时长。
|
|
249
|
+
init_params.audio_option = get_platform_audio_option();
|
|
250
|
+
rc = tc_iot_aitalk_init(&init_params, &observer, NULL);
|
|
251
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
252
|
+
goto cleanup;
|
|
253
|
+
}
|
|
254
|
+
aitalk_inited = true;
|
|
255
|
+
|
|
256
|
+
// 5. 如需机器人触发联系人呼叫,在开始对话前注册联系人。
|
|
257
|
+
// tc_iot_aitalk_register_contacts(contacts, contact_count, on_register_contacts);
|
|
258
|
+
|
|
259
|
+
// 6. 初始化具体平台的麦克风和扬声器。
|
|
260
|
+
// 麦克风采集到一帧音频后,调用 on_mic_captured() 发送给 AI 对话服务。
|
|
261
|
+
|
|
262
|
+
// 7. 异步开始持续对话,成功后再启动麦克风采集。
|
|
263
|
+
s_start_done = false;
|
|
264
|
+
rc = tc_iot_aitalk_start_speak(TC_IOT_AITALK_MODE_CONTINUOUS, on_start_speak);
|
|
265
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
266
|
+
goto cleanup;
|
|
267
|
+
}
|
|
268
|
+
wait_until(&s_start_done, 30000);
|
|
269
|
+
if (!s_start_done || s_start_result != TC_IOT_ERR_SUCCESS) {
|
|
270
|
+
goto cleanup;
|
|
271
|
+
}
|
|
272
|
+
speak_started = true;
|
|
273
|
+
|
|
274
|
+
// 启动具体平台的麦克风采集流程。
|
|
275
|
+
// 采集线程或回调中不要阻塞过久,按帧调用 on_mic_captured()。
|
|
276
|
+
|
|
277
|
+
while (!s_aitalk_error && !is_exit_requested()) {
|
|
278
|
+
// 使用具体平台的休眠、事件循环或任务调度机制。
|
|
279
|
+
}
|
|
280
|
+
conversation_completed = !s_aitalk_error;
|
|
281
|
+
|
|
282
|
+
cleanup:
|
|
283
|
+
// 先停止具体平台的麦克风采集和扬声器播放。
|
|
284
|
+
if (speak_started) {
|
|
285
|
+
tc_iot_aitalk_stop_speak();
|
|
286
|
+
}
|
|
287
|
+
if (aitalk_inited) {
|
|
288
|
+
tc_iot_aitalk_deinit();
|
|
289
|
+
}
|
|
290
|
+
if (s_data_model_done) {
|
|
291
|
+
tc_iot_data_model_deinit();
|
|
292
|
+
}
|
|
293
|
+
if (sdk_inited) {
|
|
294
|
+
tc_iot_deinit();
|
|
295
|
+
}
|
|
296
|
+
return conversation_completed ? 0 : 1;
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
4. 设备端运行,然后说:“查询当前电量”,观察是否生效。
|
|
300
|
+
|
|
301
|
+
``` bash
|
|
302
|
+
[aitalk] asr: 查一下现在电量是多少
|
|
303
|
+
[aitalk] bot_state changed: 1 -> 2
|
|
304
|
+
[IOT_SDK] 2026-09-15 17:11:23.311 I 37213-1799483392|data_model_action.c:71|create_data_model_action_from_json_string|-action parsed: action_id=get_battery, token=v2528563118rKTQu::bb0adb2e-f960-43a9-b15e-e9c945b7458f, input_data_num=0
|
|
305
|
+
[aitalk] [demo] receive new action: id=get_battery, input_num=0
|
|
306
|
+
|
|
307
|
+
[aitalk] [demo] current battery: 58
|
|
308
|
+
[IOT_SDK] 2026-09-15 17:11:23.311 I 37213-1799483392|data_model_action.c:202|data_model_on_receive_action_message|-action callback executed, action_id=get_battery, result=0
|
|
309
|
+
[IOT_SDK] 2026-09-15 17:11:23.348 I 37213-1799483392|mqtt_connection.c:1022|_mqtt_on_puback_packet_received|-puback received: packet_id=10 topic=$thing/up/action/YDBF3QFF7F/test_002
|
|
310
|
+
[aitalk] bot_state changed: 2 -> 3
|
|
311
|
+
[aitalk] bot: 小明,
|
|
312
|
+
[aitalk] bot: 现在电量是百分之五十八。
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### 案例二:控制设备音量
|
|
316
|
+
1. 在腾讯云物联网开发平台 [控制台](https://console.cloud.tencent.com/iotexplorer/v2) 产品详情页的功能定义页面,单击**新增功能**,定义一个音量控制行为。
|
|
317
|
+
|
|
318
|
+
2. 在控制台 **TWeTalk 智能体配置**页面,进入对应智能体的**工具配置**,单击**创建工具**:
|
|
319
|
+
|
|
320
|
+
| 配置项 | 说明 | |
|
|
321
|
+
| --- | --- | --- |
|
|
322
|
+
| 工具类型 | 默认选择 <strong>IoT 工具</strong>。 | |
|
|
323
|
+
| 工具名称 | 和定义行为中的标识符保持一致,当前为:<strong>control_volume</strong>。 | |
|
|
324
|
+
| 工具描述 | 和定义行为中的描述保持一致,当前为:当用户要查询当前设备音量,或需要调高、调低、调整音量时调用。 | |
|
|
325
|
+
| 工具参数 | control_type | 设备控制类型,枚举类型。取值如下:<br>- 0:只查询当前设备音量。<br>- 1:设置设备音量。<br>- 2:步进增大音量。<br>- 3:步进减少音量。 |
|
|
326
|
+
| volume | 取值含义与 control_type 相关:<br>- 0:该值无意义。<br>- 1:表示需要设置的音量。<br>- 2:表示音量增量,未指定时默认10。<br>- 3:表示音量减量,未指定时默认10。 | |
|
|
327
|
+
| 输出参数 | 行为执行结果的数据项:<strong>current_volume</strong>(整型,当前音量),需与物模型定义的输出参数保持一致。 | |
|
|
328
|
+
|
|
329
|
+
> **说明:**
|
|
330
|
+
>
|
|
331
|
+
> - 工具参数数量需与自定义行为(物模型)中定义的参数数量一致。
|
|
332
|
+
> - 工具参数的描述应尽量详细,便于 LLM 准确调用,减少幻觉。
|
|
333
|
+
> - 工具描述也要尽可能准确,如果发现 LLM 执行工具情况不理想,则需要调整这里的描述,提高工具调用命中率。
|
|
334
|
+
|
|
335
|
+
3. 在 [AI 对话的设备端 SDK](https://cloud.tencent.com/document/product/1081/137894) 集成 [物模型通信](https://cloud.tencent.com/document/product/1081/135031) 能力:
|
|
336
|
+
|
|
337
|
+
``` c
|
|
338
|
+
#include <stdbool.h>
|
|
339
|
+
#include <stdlib.h>
|
|
340
|
+
#include <string.h>
|
|
341
|
+
|
|
342
|
+
#include "tc_iot.h"
|
|
343
|
+
#include "tc_iot_aitalk.h"
|
|
344
|
+
#include "tc_iot_data_model.h"
|
|
345
|
+
|
|
346
|
+
/* 登录和开始对话均为异步操作,回调中记录结果,主流程据此继续或退出。 */
|
|
347
|
+
static volatile bool s_login_done = false;
|
|
348
|
+
static volatile bool s_start_done = false;
|
|
349
|
+
static volatile bool s_aitalk_error = false;
|
|
350
|
+
static volatile bool s_data_model_done = false;
|
|
351
|
+
static tc_iot_error_e s_login_result = TC_IOT_ERR_SUCCESS;
|
|
352
|
+
static tc_iot_error_e s_start_result = TC_IOT_ERR_SUCCESS;
|
|
353
|
+
|
|
354
|
+
static data_model_data_item_t s_action_output[1];
|
|
355
|
+
|
|
356
|
+
static void on_login(tc_iot_error_e error_code, const char *error_message) {
|
|
357
|
+
s_login_result = error_code;
|
|
358
|
+
s_login_done = true;
|
|
359
|
+
// 登录失败时,可在这里记录 error_message 并通知上层业务。
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
static void on_start_speak(tc_iot_error_e error_code, const char *error_message) {
|
|
363
|
+
s_start_result = error_code;
|
|
364
|
+
s_start_done = true;
|
|
365
|
+
// 开始对话失败时,可在这里记录 error_message 并通知上层业务。
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
static void on_receive_bot_audio(const tc_iot_audio_frame *frame, void *user_data) {
|
|
369
|
+
(void)user_data;
|
|
370
|
+
if (!frame || !frame->data || frame->data_size == 0) {
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
// 这里收到的音频是经过解码后的 PCM 音频
|
|
374
|
+
// 将 frame->data 推送到具体的音频设备播放。
|
|
375
|
+
// 例如:调用芯片平台的扬声器播放、PCM 输出或音频框架接口。
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
static void on_receive_bot_text(const char *text, void *user_data) {
|
|
379
|
+
(void)user_data;
|
|
380
|
+
if (!text) {
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
// 将机器人回复文本显示到屏幕,或上传到您的业务服务。
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
static void on_receive_asr_text(const char *text, void *user_data) {
|
|
387
|
+
(void)user_data;
|
|
388
|
+
if (!text) {
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
// 将用户语音识别结果显示到屏幕,或用于本地业务处理。
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
static void on_bot_state_changed(tc_iot_aitalk_bot_state_e old_state,
|
|
395
|
+
tc_iot_aitalk_bot_state_e new_state,
|
|
396
|
+
void *user_data) {
|
|
397
|
+
(void)old_state;
|
|
398
|
+
(void)user_data;
|
|
399
|
+
// 根据 new_state 更新设备指示灯、屏幕或其他交互状态。
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
static void on_aitalk_error(tc_iot_error_e error_code, const char *error_message,
|
|
403
|
+
void *user_data) {
|
|
404
|
+
(void)user_data;
|
|
405
|
+
s_aitalk_error = true;
|
|
406
|
+
// 记录 error_code 和 error_message,并停止或重试业务流程。
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/*
|
|
410
|
+
* 在平台麦克风的数据回调中调用本函数。
|
|
411
|
+
* data、size、codec 和 pts_ms 均来自当前平台的音频采集结果。
|
|
412
|
+
*/
|
|
413
|
+
static void on_mic_captured(const uint8_t *data, uint32_t size,
|
|
414
|
+
tc_iot_audio_codec_e codec, uint64_t pts_ms,
|
|
415
|
+
void *user_data) {
|
|
416
|
+
(void)user_data;
|
|
417
|
+
if (!data || size == 0) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
tc_iot_audio_frame frame = {0};
|
|
422
|
+
frame.codec = codec;
|
|
423
|
+
frame.sample_rate = TC_IOT_AUDIO_SAMPLE_RATE_16000;
|
|
424
|
+
frame.channels = TC_IOT_AUDIO_CHANNEL_MONO;
|
|
425
|
+
frame.frame_duration_ms = 20;
|
|
426
|
+
frame.data = (uint8_t *)data;
|
|
427
|
+
frame.data_size = size;
|
|
428
|
+
frame.pts_ms = pts_ms;
|
|
429
|
+
|
|
430
|
+
tc_iot_error_e rc = tc_iot_aitalk_send_audio(&frame);
|
|
431
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
432
|
+
// 记录发送失败原因;必要时停止采集或触发重连。
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// ==================== 物模型通信 ====================
|
|
437
|
+
// 属性上报结果回调
|
|
438
|
+
static void on_report_property_result_cb(char *property_id, void *user_data,
|
|
439
|
+
data_model_report_result_t result_code) {
|
|
440
|
+
(void)user_data;
|
|
441
|
+
printf("[demo] report property result: id=%s, code=%d\n",
|
|
442
|
+
property_id ? property_id : "(null)", (int)result_code);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// 事件上报结果回调
|
|
446
|
+
static void on_report_event_result_cb(char *event_id, void *user_data,
|
|
447
|
+
data_model_report_result_t result_code) {
|
|
448
|
+
(void)user_data;
|
|
449
|
+
printf("[demo] report event result: id=%s, code=%d\n",
|
|
450
|
+
event_id ? event_id : "(null)", (int)result_code);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// 云端修改属性
|
|
454
|
+
static void on_receive_property_changed_cb(char *property_id,
|
|
455
|
+
tc_iot_data_model_property_t *data_model_property) {
|
|
456
|
+
if (!property_id || !data_model_property) {
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
data_model_data_item_t *item = &data_model_property->property;
|
|
460
|
+
printf("[demo] property changed: id=%s, type=%d\n", item->data_id, (int)item->data_type);
|
|
461
|
+
// 按 item->data_type 解析 item->data_value 并更新本地状态 ...
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// 云端下发行为
|
|
465
|
+
static int on_receive_new_action_cb(char *action_id,
|
|
466
|
+
tc_iot_data_model_action_t *data_model_action) {
|
|
467
|
+
if (!action_id || !data_model_action) {
|
|
468
|
+
return -1;
|
|
469
|
+
}
|
|
470
|
+
printf("[demo] receive new action: id=%s, input_num=%u\n", action_id,
|
|
471
|
+
(unsigned)data_model_action->action_input_data_num);
|
|
472
|
+
// 查询电量
|
|
473
|
+
if (!strcmp(action_id, "get_battery")) {
|
|
474
|
+
// 模拟电量,真实业务请接入真实电量百分比
|
|
475
|
+
static int battery = 58;
|
|
476
|
+
s_action_output[0].data_id = "battery";
|
|
477
|
+
s_action_output[0].data_type = DATA_MODEL_DATA_TYPE_INT;
|
|
478
|
+
s_action_output[0].data_value.value_int = battery--;
|
|
479
|
+
// 先填好数据再设置数量,避免出现数量与列表不一致的中间状态
|
|
480
|
+
data_model_action->action_output_data_num = 1;
|
|
481
|
+
data_model_action->action_output_data_list = s_action_output;
|
|
482
|
+
printf("[demo] current battery: %d\n", s_action_output[0].data_value.value_int);
|
|
483
|
+
} else if (!strcmp(action_id, "control_volume")) {
|
|
484
|
+
// 模拟音量控制
|
|
485
|
+
static int volume = 50;
|
|
486
|
+
// 先校验参数个数与列表指针,避免越界访问
|
|
487
|
+
if (data_model_action->action_input_data_num < 2 ||
|
|
488
|
+
!data_model_action->action_input_data_list) {
|
|
489
|
+
return -1;
|
|
490
|
+
}
|
|
491
|
+
data_model_data_item_t *in0 = &data_model_action->action_input_data_list[0];
|
|
492
|
+
data_model_data_item_t *in1 = &data_model_action->action_input_data_list[1];
|
|
493
|
+
if (!in0->data_id || !in1->data_id) {
|
|
494
|
+
return -1;
|
|
495
|
+
}
|
|
496
|
+
if (!strcmp(in0->data_id, "control_type") && in0->data_type == DATA_MODEL_DATA_TYPE_INT) {
|
|
497
|
+
// 未携带增减量时按工具描述约定的默认值 10 处理
|
|
498
|
+
int step = (in1->data_value.value_int > 0) ? in1->data_value.value_int : 10;
|
|
499
|
+
switch (in0->data_value.value_int) {
|
|
500
|
+
// 获取当前音量
|
|
501
|
+
case 0:
|
|
502
|
+
printf("[demo] volume control: get\n");
|
|
503
|
+
break;
|
|
504
|
+
// 设置音量
|
|
505
|
+
case 1:
|
|
506
|
+
printf("[demo] volume control: set\n");
|
|
507
|
+
volume = in1->data_value.value_int;
|
|
508
|
+
break;
|
|
509
|
+
// 调高音量
|
|
510
|
+
case 2:
|
|
511
|
+
printf("[demo] volume control: increase\n");
|
|
512
|
+
volume += step;
|
|
513
|
+
break;
|
|
514
|
+
// 调低音量
|
|
515
|
+
case 3:
|
|
516
|
+
printf("[demo] volume control: decrease\n");
|
|
517
|
+
volume -= step;
|
|
518
|
+
break;
|
|
519
|
+
default:
|
|
520
|
+
printf("[demo] volume control: unknown type %d\n", in0->data_value.value_int);
|
|
521
|
+
}
|
|
522
|
+
// 音量统一收敛到 0 ~ 100
|
|
523
|
+
if (volume < 0) {
|
|
524
|
+
volume = 0;
|
|
525
|
+
} else if (volume > 100) {
|
|
526
|
+
volume = 100;
|
|
527
|
+
}
|
|
528
|
+
s_action_output[0].data_id = "current_volume";
|
|
529
|
+
s_action_output[0].data_type = DATA_MODEL_DATA_TYPE_INT;
|
|
530
|
+
s_action_output[0].data_value.value_int = volume;
|
|
531
|
+
// 先填好数据再设置数量,避免出现数量与列表不一致的中间状态
|
|
532
|
+
data_model_action->action_output_data_num = 1;
|
|
533
|
+
data_model_action->action_output_data_list = s_action_output;
|
|
534
|
+
printf("[demo] current volume: %d\n", s_action_output[0].data_value.value_int);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
return 0;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
int main(void) {
|
|
541
|
+
bool sdk_inited = false;
|
|
542
|
+
bool aitalk_inited = false;
|
|
543
|
+
bool speak_started = false;
|
|
544
|
+
bool conversation_completed = false;
|
|
545
|
+
tc_iot_error_e rc;
|
|
546
|
+
|
|
547
|
+
// 1. 配置并初始化 SDK。
|
|
548
|
+
tc_iot_config_s sdk_config = {0};
|
|
549
|
+
sdk_config.storage_path = "./";
|
|
550
|
+
sdk_config.log_level = TC_IOT_LOG_LEVEL_INFO;
|
|
551
|
+
rc = tc_iot_init(&sdk_config);
|
|
552
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
553
|
+
goto cleanup;
|
|
554
|
+
}
|
|
555
|
+
sdk_inited = true;
|
|
556
|
+
|
|
557
|
+
// 2. 从安全配置中读取设备三元组并登录平台。
|
|
558
|
+
tc_iot_device_info_s device_info = {0};
|
|
559
|
+
device_info.product_id = get_product_id();
|
|
560
|
+
device_info.device_id = get_device_name();
|
|
561
|
+
device_info.device_secret = get_device_secret();
|
|
562
|
+
device_info.region = "ap-guangzhou";
|
|
563
|
+
|
|
564
|
+
s_login_done = false;
|
|
565
|
+
rc = tc_iot_login(&device_info, on_login);
|
|
566
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
567
|
+
goto cleanup;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// 等待 on_login 回调或超时;休眠接口请替换为具体平台实现。
|
|
571
|
+
wait_until(&s_login_done, 30000);
|
|
572
|
+
if (!s_login_done || s_login_result != TC_IOT_ERR_SUCCESS) {
|
|
573
|
+
goto cleanup;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// 3. 初始化物模型
|
|
577
|
+
tc_iot_data_model_callback_t callback = {
|
|
578
|
+
.on_report_property_result_cb = on_report_property_result_cb,
|
|
579
|
+
.on_receive_property_changed_cb = on_receive_property_changed_cb,
|
|
580
|
+
.on_report_event_result_cb = on_report_event_result_cb,
|
|
581
|
+
.on_receive_new_action_cb = on_receive_new_action_cb,
|
|
582
|
+
};
|
|
583
|
+
rc = tc_iot_data_model_init(callback);
|
|
584
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
585
|
+
goto cleanup;
|
|
586
|
+
}
|
|
587
|
+
s_data_model_done = true;
|
|
588
|
+
|
|
589
|
+
// 4. 注册 AI 对话事件回调并初始化模块。
|
|
590
|
+
tc_iot_aitalk_observer_s observer = {0};
|
|
591
|
+
observer.on_receive_bot_audio = on_receive_bot_audio;
|
|
592
|
+
observer.on_receive_bot_text = on_receive_bot_text;
|
|
593
|
+
observer.on_receive_asr_text = on_receive_asr_text;
|
|
594
|
+
observer.on_bot_state_changed = on_bot_state_changed;
|
|
595
|
+
observer.on_error = on_aitalk_error;
|
|
596
|
+
|
|
597
|
+
tc_iot_aitalk_init_params_s init_params = {0};
|
|
598
|
+
// 根据实际情况配置 agent-id prompt_variables_json
|
|
599
|
+
// 根据实际采集参数设置编码、采样率和单帧时长。
|
|
600
|
+
init_params.audio_option = get_platform_audio_option();
|
|
601
|
+
rc = tc_iot_aitalk_init(&init_params, &observer, NULL);
|
|
602
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
603
|
+
goto cleanup;
|
|
604
|
+
}
|
|
605
|
+
aitalk_inited = true;
|
|
606
|
+
|
|
607
|
+
// 5. 如需机器人触发联系人呼叫,在开始对话前注册联系人。
|
|
608
|
+
// tc_iot_aitalk_register_contacts(contacts, contact_count, on_register_contacts);
|
|
609
|
+
|
|
610
|
+
// 6. 初始化具体平台的麦克风和扬声器。
|
|
611
|
+
// 麦克风采集到一帧音频后,调用 on_mic_captured() 发送给 AI 对话服务。
|
|
612
|
+
|
|
613
|
+
// 7. 异步开始持续对话,成功后再启动麦克风采集。
|
|
614
|
+
s_start_done = false;
|
|
615
|
+
rc = tc_iot_aitalk_start_speak(TC_IOT_AITALK_MODE_CONTINUOUS, on_start_speak);
|
|
616
|
+
if (rc != TC_IOT_ERR_SUCCESS) {
|
|
617
|
+
goto cleanup;
|
|
618
|
+
}
|
|
619
|
+
wait_until(&s_start_done, 30000);
|
|
620
|
+
if (!s_start_done || s_start_result != TC_IOT_ERR_SUCCESS) {
|
|
621
|
+
goto cleanup;
|
|
622
|
+
}
|
|
623
|
+
speak_started = true;
|
|
624
|
+
|
|
625
|
+
// 启动具体平台的麦克风采集流程。
|
|
626
|
+
// 采集线程或回调中不要阻塞过久,按帧调用 on_mic_captured()。
|
|
627
|
+
|
|
628
|
+
while (!s_aitalk_error && !is_exit_requested()) {
|
|
629
|
+
// 使用具体平台的休眠、事件循环或任务调度机制。
|
|
630
|
+
}
|
|
631
|
+
conversation_completed = !s_aitalk_error;
|
|
632
|
+
|
|
633
|
+
cleanup:
|
|
634
|
+
// 先停止具体平台的麦克风采集和扬声器播放。
|
|
635
|
+
if (speak_started) {
|
|
636
|
+
tc_iot_aitalk_stop_speak();
|
|
637
|
+
}
|
|
638
|
+
if (aitalk_inited) {
|
|
639
|
+
tc_iot_aitalk_deinit();
|
|
640
|
+
}
|
|
641
|
+
if (s_data_model_done) {
|
|
642
|
+
tc_iot_data_model_deinit();
|
|
643
|
+
}
|
|
644
|
+
if (sdk_inited) {
|
|
645
|
+
tc_iot_deinit();
|
|
646
|
+
}
|
|
647
|
+
return conversation_completed ? 0 : 1;
|
|
648
|
+
}
|
|
649
|
+
```
|
|
650
|
+
4. 设备端运行,然后说出音量相关指令,观察是否生效。
|
|
651
|
+
|
|
652
|
+
``` bash
|
|
653
|
+
[aitalk] asr: 现在音量是多少
|
|
654
|
+
[aitalk] bot_state changed: 1 -> 2
|
|
655
|
+
[IOT_SDK] 2026-09-15 20:42:52.735 I 7611-1878175744|data_model_action.c:71|create_data_model_action_from_json_string|-action parsed: action_id=control_volume, token=v2342464055QgFuz::0cf5e3ee-71ef-4d73-9f1f-ce90193f2705, input_data_num=2
|
|
656
|
+
[aitalk] [demo] receive new action: id=control_volume, input_num=2
|
|
657
|
+
[aitalk] [demo] volume control: get
|
|
658
|
+
[aitalk] [demo] current volume: 50
|
|
659
|
+
[IOT_SDK] 2026-09-15 20:42:52.735 I 7611-1878175744|data_model_action.c:202|data_model_on_receive_action_message|-action callback executed, action_id=control_volume, result=0
|
|
660
|
+
[IOT_SDK] 2026-09-15 20:42:52.767 I 7611-1878175744|mqtt_connection.c:1022|_mqtt_on_puback_packet_received|-puback received: packet_id=10 topic=$thing/up/action/YDBF3QFF7F/test_002
|
|
661
|
+
[aitalk] bot_state changed: 2 -> 3
|
|
662
|
+
[aitalk] bot: 现在音量是百分之五十。
|
|
663
|
+
[aitalk] bot:
|
|
664
|
+
[aitalk] bot_state changed: 3 -> 5
|
|
665
|
+
[aitalk] bot_state changed: 5 -> 1
|
|
666
|
+
[aitalk] asr: 调高音量
|
|
667
|
+
[aitalk] bot_state changed: 1 -> 2
|
|
668
|
+
[IOT_SDK] 2026-09-15 20:43:00.311 I 7611-1878175744|data_model_action.c:71|create_data_model_action_from_json_string|-action parsed: action_id=control_volume, token=v2520474960gcquE::78fb4b5c-d422-44d4-8518-c9a7613892f6, input_data_num=2
|
|
669
|
+
[aitalk] [demo] receive new action: id=control_volume, input_num=2
|
|
670
|
+
[aitalk] [demo] volume control: increase
|
|
671
|
+
[aitalk] [demo] current volume: 60
|
|
672
|
+
[IOT_SDK] 2026-09-15 20:43:00.311 I 7611-1878175744|data_model_action.c:202|data_model_on_receive_action_message|-action callback executed, action_id=control_volume, result=0
|
|
673
|
+
[IOT_SDK] 2026-09-15 20:43:00.343 I 7611-1878175744|mqtt_connection.c:1022|_mqtt_on_puback_packet_received|-puback received: packet_id=11 topic=$thing/up/action/YDBF3QFF7F/test_002
|
|
674
|
+
[aitalk] bot_state changed: 2 -> 3
|
|
675
|
+
[aitalk] bot: 已经帮你调高啦,
|
|
676
|
+
[aitalk] bot: 现在音量是百分之六十。
|
|
677
|
+
[aitalk] bot:
|
|
678
|
+
[aitalk] bot_state changed: 3 -> 5
|
|
679
|
+
[aitalk] bot_state changed: 5 -> 1
|
|
680
|
+
[aitalk] asr: 音量调到27%
|
|
681
|
+
[aitalk] bot_state changed: 1 -> 2
|
|
682
|
+
[IOT_SDK] 2026-09-15 20:43:10.239 I 7611-1878175744|data_model_action.c:71|create_data_model_action_from_json_string|-action parsed: action_id=control_volume, token=v2521859385OnQNt::4c3df927-ed64-4a19-add4-f54ee70f0533, input_data_num=2
|
|
683
|
+
[aitalk] [demo] receive new action: id=control_volume, input_num=2
|
|
684
|
+
[aitalk] [demo] volume control: set
|
|
685
|
+
[aitalk] [demo] current volume: 27
|
|
686
|
+
[IOT_SDK] 2026-09-15 20:43:10.240 I 7611-1878175744|data_model_action.c:202|data_model_on_receive_action_message|-action callback executed, action_id=control_volume, result=0
|
|
687
|
+
[IOT_SDK] 2026-09-15 20:43:10.272 I 7611-1878175744|mqtt_connection.c:1022|_mqtt_on_puback_packet_received|-puback received: packet_id=12 topic=$thing/up/action/YDBF3QFF7F/test_002
|
|
688
|
+
[aitalk] bot_state changed: 2 -> 3
|
|
689
|
+
[aitalk] bot: 好,
|
|
690
|
+
[aitalk] bot: 已经调到百分之二十七了。
|
|
691
|
+
[aitalk] bot:
|
|
692
|
+
[aitalk] bot_state changed: 3 -> 5
|
|
693
|
+
[aitalk] bot_state changed: 5 -> 1
|
|
694
|
+
[aitalk] asr: 音量调低5
|
|
695
|
+
[aitalk] bot_state changed: 1 -> 2
|
|
696
|
+
[IOT_SDK] 2026-09-15 20:43:18.861 I 7611-1878175744|data_model_action.c:71|create_data_model_action_from_json_string|-action parsed: action_id=control_volume, token=v2342464055ebTar::92929726-51af-4197-b2e0-0fd6cdbe1f1f, input_data_num=2
|
|
697
|
+
[aitalk] [demo] receive new action: id=control_volume, input_num=2
|
|
698
|
+
[aitalk] [demo] volume control: decrease
|
|
699
|
+
[aitalk] [demo] current volume: 22
|
|
700
|
+
[IOT_SDK] 2026-09-15 20:43:18.861 I 7611-1878175744|data_model_action.c:202|data_model_on_receive_action_message|-action callback executed, action_id=control_volume, result=0
|
|
701
|
+
[IOT_SDK] 2026-09-15 20:43:18.894 I 7611-1878175744|mqtt_connection.c:1022|_mqtt_on_puback_packet_received|-puback received: packet_id=13 topic=$thing/up/action/YDBF3QFF7F/test_002
|
|
702
|
+
[aitalk] bot_state changed: 2 -> 3
|
|
703
|
+
[aitalk] bot: 好,
|
|
704
|
+
[aitalk] bot: 降了五个点,现在音量是百分之二十二。
|
|
705
|
+
[aitalk] bot:
|
|
706
|
+
[aitalk] bot_state changed: 3 -> 5
|
|
707
|
+
[aitalk] bot_state changed: 5 -> 1
|
|
708
|
+
[aitalk] asr: 当前音量是多少
|
|
709
|
+
[aitalk] bot_state changed: 1 -> 2
|
|
710
|
+
[IOT_SDK] 2026-09-15 20:43:29.919 I 7611-1878175744|data_model_action.c:71|create_data_model_action_from_json_string|-action parsed: action_id=control_volume, token=v2342464055rmPhU::c44aad0c-2633-44e9-bc75-2da1f087babd, input_data_num=2
|
|
711
|
+
[aitalk] [demo] receive new action: id=control_volume, input_num=2
|
|
712
|
+
[aitalk] [demo] volume control: get
|
|
713
|
+
[aitalk] [demo] current volume: 22
|
|
714
|
+
[IOT_SDK] 2026-09-15 20:43:29.919 I 7611-1878175744|data_model_action.c:202|data_model_on_receive_action_message|-action callback executed, action_id=control_volume, result=0
|
|
715
|
+
[IOT_SDK] 2026-09-15 20:43:29.951 I 7611-1878175744|mqtt_connection.c:1022|_mqtt_on_puback_packet_received|-puback received: packet_id=14 topic=$thing/up/action/YDBF3QFF7F/test_002
|
|
716
|
+
[aitalk] bot_state changed: 2 -> 3
|
|
717
|
+
[aitalk] bot: 现在音量是百分之二十二。
|
|
718
|
+
[aitalk] bot:
|
|
719
|
+
[aitalk] bot_state changed: 3 -> 5
|
|
720
|
+
[aitalk] bot_state changed: 5 -> 1
|
|
721
|
+
```
|