389 lines
15 KiB
C
Raw Normal View History

#include <common/sys_config.h>
#include <components/log.h>
#include <modules/wifi.h>
#include <components/netif.h>
#include <components/event.h>
#include <string.h>
#include "bk_private/bk_init.h"
#include <components/system.h>
#include <os/os.h>
#include "components/webclient.h"
#include "cJSON.h"
#include "components/bk_uid.h"
#include "bk_genie_comm.h"
#include "thing.h"
#include "iot_lamp.h"
#include "iot_speaker.h"
#include "iot_sleep_helper.h"
#include "bat_main.h"
#include "application.h"
#include "mcp/mcp_server.h"
#include "beken_rtc.h"
#if (CONFIG_SYS_CPU0)
#include "beken_config.h"
#include "aud_intf.h"
#include "bk_factory_config.h"
#if CONFIG_NETWORK_AUTO_RECONNECT
#include "bk_genie_smart_config.h"
#endif
#endif
#include "iot_lamp.h"
#include "iot_speaker.h"
#include "iot_sleep_helper.h"
#include "bat_main.h"
#include "spi_led.h"
#include "app_event.h"
#define TAG "APP"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
2025-07-12 02:11:33 +08:00
static DeviceState deviceState = kDeviceStateIdle;
static ReturnValue sleep_helper_set_mode_callback(const PropertyList* properties) {
Property* mode_prop = property_list_get_by_name(properties, "mode");
if (!mode_prop || property_get_type(mode_prop) != PROPERTY_TYPE_INTEGER) {
return return_value_create_string("{\"error\":\"Invalid level parameter\"}");
}
int mode = property_get_integer_value(mode_prop);
sleep_helper_set_mode(mode);
LOGE("sleep_helper_setmode ->%d\n",mode);
return return_value_create_string("{\"success\":true}");
}
static ReturnValue sleep_helper_set_level_callback(const PropertyList* properties) {
Property* level_prop = property_list_get_by_name(properties, "level");
if (!level_prop || property_get_type(level_prop) != PROPERTY_TYPE_INTEGER) {
return return_value_create_string("{\"error\":\"Invalid level parameter\"}");
}
int level = property_get_integer_value(level_prop);
sleep_helper_set_level(level);
LOGE("sleep_helper_set_level ->%d\n",level);
return return_value_create_string("{\"success\":true}");
}
static ReturnValue sleep_helper_open_callback(const PropertyList* properties) {
LOGE("sleep_helper_open_callback\n");
int result = sleep_helper_open();
if(result == -1){
return return_value_create_string("{\"success\":false,\"error\":\"耳夹未接入\"}");
}else{
return return_value_create_string("{\"success\":true}");
}
//return return_value_create_string("{\"success\":true}");
}
static ReturnValue sleep_helper_close_callback(const PropertyList* properties) {
LOGE("sleep_helper_close_callback\n");
sleep_helper_close();
return return_value_create_string("{\"success\":true}");
}
// 设备状态工具回调
static ReturnValue get_device_status_callback(const PropertyList* properties) {
cJSON* status = cJSON_CreateObject();
//软件版本
cJSON* application = cJSON_CreateObject();
cJSON_AddStringToObject(application, "version", APPLICATION_VERSION);
cJSON_AddItemToObject(status, "application", application);
//扬声器状态
cJSON* audio_speaker = cJSON_CreateObject();
cJSON_AddNumberToObject(audio_speaker, "volume", speaker_volume_get_current());
cJSON_AddItemToObject(status, "audio_speaker", audio_speaker);
//灯光状态 不需要获取 肉眼所见
cJSON* light = cJSON_CreateObject();
cJSON_AddNumberToObject(light, "brightness", lamp_get_bright());
//cJSON_AddStringToObject(screen, "theme", "light");
cJSON_AddItemToObject(status, "light", light);
//电池状态
cJSON* battery = cJSON_CreateObject();
cJSON_AddNumberToObject(battery, "level", battery_get_percent());
cJSON_AddItemToObject(status, "battery", battery);
char *jsonString = cJSON_PrintUnformatted(status);
ReturnValue ret = return_value_create_string(jsonString);
cJSON_Delete(status);
return ret;
}
// 设置音量工具回调
static ReturnValue set_volume_callback(const PropertyList* properties) {
Property* volume_prop = property_list_get_by_name(properties, "volume");
if (!volume_prop || property_get_type(volume_prop) != PROPERTY_TYPE_INTEGER) {
return return_value_create_string("{\"error\":\"Invalid volume parameter\"}");
}
int volume = property_get_integer_value(volume_prop);
LOGE("board_set_volume ->%d\n",volume);
//board_set_volume(volume);
//uint32_t speaker_volume_get_current();
speaker_set_volume(volume);
return return_value_create_string("{\"success\":true}");
}
// 设置亮度工具回调
static ReturnValue set_brightness_callback(const PropertyList* properties) {
Property* brightness_prop = property_list_get_by_name(properties, "brightness");
if (!brightness_prop || property_get_type(brightness_prop) != PROPERTY_TYPE_INTEGER) {
return return_value_create_string("{\"error\":\"Invalid brightness parameter\"}");
}
int brightness = property_get_integer_value(brightness_prop);
if(brightness == 0){
ws2812_led_clear_all();
}else{
//ws2812_set_all_led(0xFFFFFF,brightness);
ws2812_set_all_led_brightness(brightness);
}
LOGE("board_set_brightness ->%d\n",brightness);
return return_value_create_string("{\"success\":true}");
}
// 设置主题工具回调
static ReturnValue set_theme_callback(const PropertyList* properties) {
Property* theme_prop = property_list_get_by_name(properties, "theme");
if (!theme_prop || property_get_type(theme_prop) != PROPERTY_TYPE_STRING) {
return return_value_create_string("{\"error\":\"Invalid theme parameter\"}");
}
const char* theme = property_get_string_value(theme_prop);
LOGE("board_set_theme ->%s\n",theme);
return return_value_create_string("{\"success\":true}");
}
// 拍照工具回调
static ReturnValue take_photo_callback(const PropertyList* properties) {
ReturnValue ret = return_value_create_string("photo_data");
return ret;
}
// OTA升级检测工具回调
static ReturnValue ota_update_device_callback(const PropertyList* properties) {
// ReturnValue ret = return_value_create_string("photo_data");
// 电量低于25 不允许执行OTA
int battery = battery_get_percent();
if (battery < 25)
{
LOGE("power low bat:%d ,don't ota !!\n", battery);
app_event_send_msg(APP_EVT_LOW_VOLTAGE, 0);
return return_value_create_string("{\"success\":false,\"error\":\"电量低,不允许升级设备\"}");
}
iot_lamp_check_ota();
return return_value_create_string("{\"success\":true}");
}
// 设备助眠仪状态回调
static ReturnValue sleep_helper_get_device_status_callback(const PropertyList* properties) {
cJSON* status = cJSON_CreateObject();
//助眠仪的状态
cJSON* sleep_helper = cJSON_CreateObject();
cJSON_AddNumberToObject(sleep_helper, "model", sleep_helper_get_mode());
cJSON_AddNumberToObject(sleep_helper, "level", sleep_helper_get_level());
cJSON_AddItemToObject(status, "sleep_helper", sleep_helper);
char *jsonString = cJSON_PrintUnformatted(status);
ReturnValue ret = return_value_create_string(jsonString);
cJSON_Delete(status);
return ret;
}
// 获取体温数据回调
static ReturnValue health_get_temperature_callback(const PropertyList* properties) {
#if 0
cJSON* status = cJSON_CreateObject();
cJSON* health = cJSON_CreateObject();
cJSON_AddNumberToObject(health, "body_temperature", 38.5);
cJSON_AddItemToObject(status, "health", health);
char *jsonString = cJSON_PrintUnformatted(status);
ReturnValue ret = return_value_create_string(jsonString);
cJSON_Delete(status);
return ret;
#endif
return return_value_create_string("{\"success\":false,\"error\":\"获取体温功能正在完善,敬请期待\"}");
}
// 获取血压数据回调
static ReturnValue health_get_bloodpressure_callback(const PropertyList* properties) {
#if 0
cJSON* status = cJSON_CreateObject();
cJSON* health = cJSON_CreateObject();
cJSON_AddNumberToObject(health, "bloodpressure", 120);
cJSON_AddItemToObject(status, "health", health);
char *jsonString = cJSON_PrintUnformatted(status);
ReturnValue ret = return_value_create_string(jsonString);
cJSON_Delete(status);
return ret;
#endif
return return_value_create_string("{\"success\":false,\"error\":\"获取血压功能正在完善,敬请期待\"}");
}
static ReturnValue health_analysis_report_callback(const PropertyList* properties) {
#if 0
cJSON* status = cJSON_CreateObject();
cJSON* health = cJSON_CreateObject();
cJSON_AddNumberToObject(health, "bloodpressure", 120);
cJSON_AddItemToObject(status, "health", health);
char *jsonString = cJSON_PrintUnformatted(status);
ReturnValue ret = return_value_create_string(jsonString);
cJSON_Delete(status);
return ret;
#endif
return return_value_create_string("{\"success\":false,\"error\":\"分析健康报告功能正在完善,敬请期待\"}");
}
void app_mcp_init(){
McpServer* mcp_server = mcp_server_get_instance();
// 助眠仪模式
{
PropertyList* props = property_list_create();
Property* prop_mode = property_create_integer("mode", false, 0, true, 0, 3);
property_list_add_property(props, prop_mode);
mcp_server_add_tool_with_params(mcp_server, "self.sleep_helper.set_mode", "设置助眠仪的模式", props, sleep_helper_set_mode_callback);
}
// 助眠仪等级
{
PropertyList* props = property_list_create();
Property* prop_level = property_create_integer("level", false, 1, true, 1, 9);
property_list_add_property(props, prop_level);
mcp_server_add_tool_with_params(mcp_server, "self.sleep_helper.set_level", "设置助眠仪的等级", props, sleep_helper_set_level_callback);
}
//打开助眠仪
{
PropertyList* props = property_list_create();
mcp_server_add_tool_with_params(mcp_server, "self.sleep_helper.open", "打开助眠仪", props, sleep_helper_open_callback);
}
//关闭助眠仪
{
PropertyList* props = property_list_create();
mcp_server_add_tool_with_params(mcp_server, "self.sleep_helper.close", "关闭助眠仪", props, sleep_helper_close_callback);
}
// 获取助眠仪状态
{
PropertyList* props = property_list_create();
mcp_server_add_tool_with_params(mcp_server, "self.sleep_helper.get_status",
"获取助眠仪状态 (mode=0 表示已经关闭, mode=1 表示模式1, mode=2 表示模式2,mode=3 表示模式3,level (0-9)分别代表9个不同等级", props, sleep_helper_get_device_status_callback);
}
// 添加获取设备状态工具
{
PropertyList* props = property_list_create();
mcp_server_add_tool_with_params(mcp_server, "self.get_device_status", "获取软件版本,设备音量,灯光亮度,设备电池状态", props, get_device_status_callback);
}
// 添加设置音量工具
{
PropertyList* props = property_list_create();
Property* volume_prop = property_create_integer("volume", false, 0, true, 0, 100);
property_list_add_property(props, volume_prop);
//Property* vol_prop = property_create_integer("vol", false, 0, true, 0, 100);
//property_list_add_property(props, vol_prop);
mcp_server_add_tool_with_params(
mcp_server,
"self.audio_speaker.set_volume",
"Set the volume of the audio speaker. If the current volume is unknown, you must call `self.get_device_status` tool first and then call this tool.",
props, set_volume_callback);
}
// 添加设置亮度工具
{
PropertyList* props = property_list_create();
Property* brightness_prop = property_create_integer("brightness", false, 0, true, 0, 100);
property_list_add_property(props, brightness_prop);
mcp_server_add_tool_with_params(mcp_server, "self.light.set_brightness", "设置拍拍灯的灯光亮度", props, set_brightness_callback);
}
// 添加拍照工具
//{
// PropertyList* props = property_list_create();
// mcp_server_add_tool_with_params(mcp_server, "take_photo", "Take a photo", props, take_photo_callback);
//}
// OTA
{
PropertyList* props = property_list_create();
mcp_server_add_tool_with_params(mcp_server, "self.ota.update_device", "更新拍拍灯乐小牛软件,执行该指令需要和用户二次确认才允许下发这个指令,并提示大约等待3分钟后手动重启设备", props, ota_update_device_callback);
}
{
PropertyList* props = property_list_create();
mcp_server_add_tool_with_params(mcp_server, "self.health.get_temperature", "获取用户最近温度数据", props, health_get_temperature_callback);
}
{
PropertyList* props = property_list_create();
mcp_server_add_tool_with_params(mcp_server, "self.health.get_bloodpressure", "获取用户最近血压数据", props, health_get_bloodpressure_callback);
}
{
PropertyList* props = property_list_create();
mcp_server_add_tool_with_params(mcp_server, "self.health.analysis_report", "获取用户最近健康分析报告", props, health_analysis_report_callback);
}
}
2025-07-12 02:11:33 +08:00
void app_set_device_state(DeviceState state){
deviceState = state;
switch(deviceState){
case kDeviceStateIdle:
LOGE("set_device_state -> idle\n");
break;
case kDeviceStateConnecting:
LOGE("set_device_state -> connecting\n");
break;
case kDeviceStateListening:
LOGE("set_device_state -> listening\n");
break;
case kDeviceStateSpeaking:
LOGE("set_device_state -> speaking\n");
break;
case kDeviceStateUpgrading:
LOGE("set_device_state -> upgrading\n");
break;
case kDeviceStateActivating:
LOGE("set_device_state -> activating\n");
break;
case kDeviceStateAudioTesting:
break;
default:
break;
}
}
void app_on_incoming_json(char *json_text, unsigned int size){
}
DeviceState app_get_device_state(){
return deviceState;
}
void app_config_init(){
//读取OTA地址
char ota_url[128] = {0};
int ret_size = bk_config_read("ai_ota_url", (void *)&ota_url, sizeof(ota_url));
if(ret_size > 0){
LOGE("bk_config_read ai_ota_url:%s\n",ota_url);
//bk_ota_set_ota_url(ota_url);
}else{
LOGE("bk_config_read ai_ota_url fail\n");
memset(ota_url, 0, sizeof(ota_url));
sprintf(ota_url, "%s",APPLICATION_DEFULT_OTA_URL);
if (0 != bk_config_write("ai_ota_url", (void *)&ota_url, sizeof(ota_url)))
{
BK_LOGE(TAG, "storage ai_ota_url: %s fail\n", ota_url);
}
}
}
void app_start(){
app_mcp_init();
}