Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/sync-to-gitee.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:

jobs:
sync:
if: github.repository == 'tuya/DuckyClaw'
if: github.repository == 'tuya/TuyaOpenClaw'
runs-on: ubuntu-latest
name: Git Repo Sync
steps:
Expand All @@ -14,6 +14,6 @@ jobs:
fetch-depth: 0
- uses: tuya/TuyaOpen@master
with:
target-url: 'https://gitee.com/tuya-open/DuckyClaw.git'
target-url: 'https://gitee.com/tuya-open/TuyaOpenClaw.git'
target-username: 'flyingcys'
target-token: ${{ secrets.GITEE_TOKEN }}
204 changes: 204 additions & 0 deletions src/app_ui_action.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
/**
* @file app_ui_action.c
* @brief app_ui_action module is used to
* @version 0.1
* @copyright Copyright (c) 2021-2026 Tuya Inc. All Rights Reserved.
*/
#include "tal_api.h"
#include <string.h>

#if defined(ENABLE_COMP_AI_DISPLAY) && (ENABLE_COMP_AI_DISPLAY == 1)
#include "ai_ui_manage.h"

#if defined(ENABLE_COMP_AI_PICTURE) && (ENABLE_COMP_AI_PICTURE == 1)
#include "image_album.h"
#include "ai_picture.h"
#include "ai_picture_input.h"
#endif

#if defined(ENABLE_COMP_AI_VIDEO) && (ENABLE_COMP_AI_VIDEO == 1)
#include "ai_video_input.h"
#endif

#if defined(ENABLE_PRINTER) && (ENABLE_PRINTER == 1)
#include "app_printer.h"
#endif

/***********************************************************
************************macro define************************
***********************************************************/


/***********************************************************
***********************typedef define***********************
***********************************************************/
#if defined(ENABLE_COMP_AI_VIDEO) && (ENABLE_COMP_AI_VIDEO == 1)
static bool sg_ai_vision_enabled = false;
#endif

/***********************************************************
***********************function define**********************
***********************************************************/
#if defined(ENABLE_COMP_AI_VIDEO) && (ENABLE_COMP_AI_VIDEO == 1)
static void __display_camera_yuv_fram(TDL_CAMERA_FRAME_T *frame)
{
AI_UI_VIDEO_T video = {0};

if (NULL == frame) {
return;
}

video.width = frame->width;
video.height = frame->height;
video.yuv422 = frame->data;
video.len = frame->data_len;

ai_ui_disp_msg_sync(AI_UI_DISP_CAMERA_FLUSH, (uint8_t*)&video, sizeof(AI_UI_VIDEO_T));
}
#endif /* ENABLE_COMP_AI_VIDEO */


static void __app_ui_action_handle(AI_UI_ACTION_E action, uint8_t *data, uint32_t len)
{
switch (action) {
#if defined(ENABLE_COMP_AI_VIDEO) && (ENABLE_COMP_AI_VIDEO == 1)
case AI_UI_ACT_OPEN_CAMERA:
sg_ai_vision_enabled = false;
ai_video_set_yuv_frame_flush_cb(__display_camera_yuv_fram);
ai_video_start();
ai_ui_disp_msg_sync(AI_UI_DISP_CAMERA_OPEN, NULL, 0);
break;

case AI_UI_ACT_TAKE_PHOTO: {
uint8_t *jpeg = NULL;
uint32_t jpeg_len = 0;
ai_video_get_jpeg_frame(&jpeg, &jpeg_len);

if (jpeg && jpeg_len) {
#if defined(ENABLE_COMP_AI_PICTURE) && (ENABLE_COMP_AI_PICTURE == 1)
char name[AI_PICTURE_NAME_MAX_LEN + 1] = {0};
ai_picture_save_to_album(jpeg, jpeg_len, NULL, name);
ai_ui_disp_msg_sync(AI_UI_DISP_CAMERA_THUMB, jpeg, jpeg_len);
#endif
if (sg_ai_vision_enabled) {
/* Close camera so the user sees the AI response in chat */
ai_video_stop();
ai_video_set_yuv_frame_flush_cb(NULL);
ai_ui_disp_msg_sync(AI_UI_DISP_CAMERA_CLOSE, NULL, 0);
#if defined(ENABLE_COMP_AI_PICTURE) && (ENABLE_COMP_AI_PICTURE == 1)
ai_ui_disp_msg(AI_UI_DISP_USER_IMAGE_LINK, (uint8_t *)name, strlen(name));

ai_picture_input_recognize(jpeg, jpeg_len);
#endif
} else {
ai_ui_disp_msg_sync(AI_UI_DISP_CAMERA_THUMB, jpeg, jpeg_len);
}

ai_video_jpeg_image_free(&jpeg);
}
} break;

case AI_UI_ACT_CLOSE_CAMER:
ai_video_stop();
ai_video_set_yuv_frame_flush_cb(NULL);
ai_ui_disp_msg_sync(AI_UI_DISP_CAMERA_CLOSE, NULL, 0);
break;

case AI_UI_ACT_CAMERA_AI_ON:
sg_ai_vision_enabled = true;
break;

case AI_UI_ACT_CAMERA_AI_OFF:
sg_ai_vision_enabled = false;
break;
#endif /* ENABLE_COMP_AI_VIDEO */

#if defined(ENABLE_COMP_AI_PICTURE) && (ENABLE_COMP_AI_PICTURE == 1)
case AI_UI_ACT_OPEN_ALBUM: {
char *album_name = ai_picture_get_album_name();
if (album_name) {
ai_ui_disp_msg_sync(AI_UI_DISP_ALBUM_OPEN, (uint8_t*)album_name, strlen(album_name));
}
} break;

case AI_UI_ACT_VIEW_PREV_IMG:
ai_ui_disp_msg_sync(AI_UI_DISP_ALBUM_VIEW_PREV, NULL, 0);
break;

case AI_UI_ACT_VIEW_NEXT_IMG:
ai_ui_disp_msg_sync(AI_UI_DISP_ALBUM_VIEW_NEXT, NULL, 0);
break;

case AI_UI_ACT_VIEW_ALL_IMG:
ai_ui_disp_msg_sync(AI_UI_DISP_ALBUM_VIEW_ALL, NULL, 0);
break;

case AI_UI_ACT_DELETE_IMG: {
char *name = (char *)data;
if (NULL == name) {
PR_ERR("image name is null");
break;
}
IMAGE_ALBUM_HANDLE hdl = image_album_find_by_name(ai_picture_get_album_name());
image_album_delete(hdl, name);
ai_ui_disp_msg_sync(AI_UI_DISP_ALBUM_RELOAD, NULL, 0);
} break;

case AI_UI_ACT_BATCH_DELETE_IMG: {
if (NULL == data || len < sizeof(AI_UI_BATCH_DELETE_T)) {
break;
}
IMAGE_ALBUM_HANDLE hdl = image_album_find_by_name(ai_picture_get_album_name());
if (NULL == hdl) {
PR_ERR("album not found for batch delete");
break;
}
AI_UI_BATCH_DELETE_T *batch = (AI_UI_BATCH_DELETE_T *)data;
uint32_t i;
for (i = 0; i < batch->count && i < AI_UI_BATCH_DELETE_MAX; i++) {
image_album_delete(hdl, batch->names[i]);
}
} break;

case AI_UI_ACT_CLOSE_ALBUM:
ai_ui_disp_msg_sync(AI_UI_DISP_ALBUM_CLOSE, NULL, 0);
break;

case AI_UI_ACT_OPEN_IMG_ATTACH_LIST:
ai_ui_disp_msg_sync(AI_UI_DISP_ALBUM_SELECT_IMG, NULL, 0);
break;

case AI_UI_ACT_ADD_IMG_ATTACH: {
ai_ui_disp_msg_sync(AI_UI_DISP_ADD_CHAT_ATTACH_IMG, data, strlen((char *)data));
ai_picture_input_add_from_album((char *)data, NULL);
} break;

case AI_UI_ACT_DEL_IMG_ATTACH: {
ai_picture_input_del_from_album((char *)data);
} break;

#if defined(ENABLE_PRINTER) && (ENABLE_PRINTER == 1)
case AI_UI_ACT_PRINT_IMG: {
if (NULL == data || 0 == len) {
PR_ERR("print: filename is null");
break;
}
OPERATE_RET print_rt = app_print_img_from_album((const char *)data);
int32_t result = (int32_t)print_rt;
ai_ui_disp_msg(AI_UI_DISP_PRINT_RESULT, (uint8_t *)&result, sizeof(result));
} break;
#endif /* ENABLE_PRINTER */

#endif /* ENABLE_IMAGE_ALBUM */
default:
break;
}
}


void app_ui_action_register(void)
{
ai_ui_action_cb_register(__app_ui_action_handle);
}

#endif
14 changes: 14 additions & 0 deletions src/tuyaopen_claw_chat.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,10 @@ static void __ai_chat_handle_event(AI_NOTIFY_EVENT_T *event)
}
}

#if defined(ENABLE_COMP_AI_DISPLAY) && (ENABLE_COMP_AI_DISPLAY == 1)
extern void app_ui_action_register(void);
#endif

OPERATE_RET tuyaopen_claw_chat_init(void)
{
OPERATE_RET rt = OPRT_OK;
Expand All @@ -233,6 +237,11 @@ OPERATE_RET tuyaopen_claw_chat_init(void)
};
TUYA_CALL_ERR_RETURN(ai_chat_init(&ai_chat_cfg));

#if defined(ENABLE_COMP_AI_DISPLAY) && (ENABLE_COMP_AI_DISPLAY == 1)
/* Register popup (+ button) action handler: camera / album / add-image attach */
app_ui_action_register();
#endif

#if defined(ENABLE_COMP_AI_VIDEO) && (ENABLE_COMP_AI_VIDEO == 1)
TUYA_CALL_ERR_LOG(ai_video_init());
TUYA_CALL_ERR_LOG(ai_video_set_yuv_frame_flush_cb(__ai_video_display_flush));
Expand All @@ -242,6 +251,11 @@ OPERATE_RET tuyaopen_claw_chat_init(void)
TUYA_CALL_ERR_RETURN(ai_mcp_init());
#endif

#if defined(ENABLE_COMP_AI_PICTURE) && (ENABLE_COMP_AI_PICTURE == 1)
/* Create/register the "ai_picture" album so album + add-image popup actions resolve */
TUYA_CALL_ERR_RETURN(ai_picture_init());
#endif

// Free heap size
tal_sw_timer_create(__printf_free_heap_tm_cb, NULL, &sg_printf_heap_tm);
tal_sw_timer_start(sg_printf_heap_tm, PRINTF_FREE_HEAP_TTIME, TAL_TIMER_CYCLE);
Expand Down
Loading