2025-07-10 11:49:34 +08:00
|
|
|
#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"
|
|
|
|
|
|
|
|
#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;
|
2025-07-10 11:49:34 +08:00
|
|
|
|
|
|
|
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) {
|
2025-07-11 01:24:10 +08:00
|
|
|
Property* level_prop = property_list_get_by_name(properties, "level");
|
2025-07-10 11:49:34 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2025-07-11 01:24:10 +08:00
|
|
|
mcp_server_add_tool_with_params(mcp_server, "self.light.set_brightness", "设置拍拍灯的灯光亮度", props, set_brightness_callback);
|
2025-07-10 11:49:34 +08:00
|
|
|
}
|
|
|
|
// 添加拍照工具
|
|
|
|
//{
|
|
|
|
// 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", "更新拍拍灯乐小牛软件,执行该指令需要和用户二次确认才允许下发这个指令", props, ota_update_device_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;
|
|
|
|
}
|
2025-07-10 11:49:34 +08:00
|
|
|
void app_start(){
|
|
|
|
app_mcp_init();
|
|
|
|
}
|