添加IOT设备控制 目前已经支持大模型控制音量

This commit is contained in:
helloyifa 2025-05-18 23:55:35 +08:00
parent df32087901
commit 947cfb995e
14 changed files with 726 additions and 39 deletions

View File

@ -38,7 +38,7 @@
//#define CONFIG_UVC_CAMERA /* config CONFIG_USB_UVC in cp1 */
#define CONFIG_DVP_CAMERA
#define SPK_GAIN_MAX (0X15)
#define SPK_GAIN_MAX (0X30)//
#define SPK_VOLUME_LEVEL (11) //[0,10]
#define BANDWIDTH_ESTIMATE_MIN_BITRATE (500000)

View File

@ -1,9 +1,10 @@
set(incs . include asr bt_pan)
set(incs . include asr bt_pan iot)
set(srcs)
list(APPEND srcs
app_main.c
spi_led.c
spi_led.c
)
if (CONFIG_SYS_CPU0)
@ -20,6 +21,9 @@ list(APPEND srcs
countdown.c
motor.c
audio_para.c
iot/iot_lamp.c
iot/iot_speaker.c
iot/thing.c
)
if (CONFIG_NETWORK_AUTO_RECONNECT)
list(APPEND srcs

View File

@ -41,6 +41,8 @@
#include "components/bluetooth/bk_dm_bluetooth.h"
#include "app_main.h"
#include "spi_led.h"
extern void user_app_main(void);
extern void rtos_set_user_app_entry(beken_thread_function_t entry);
extern int bk_cli_init(void);
@ -93,6 +95,10 @@ const struct factory_config_t s_user_config[] = {
{"user_key2", (void *)&s_user_value2, 4, BK_TRUE, 4},
};
#endif
//helloyifa
#if (CONFIG_SYS_CPU0)
#include "iot/thing.h"
#endif
static int beken_rtc_cli_init(void)
{
@ -644,6 +650,7 @@ static void handle_system_event(key_event_t event)
bk_config_write("volume", (void *)&volume, 4);
thing_init();
// spi_led_init();
#endif
#endif

View File

@ -13,7 +13,7 @@
#include <driver/aon_rtc.h>
#endif
#include "bk_genie_comm.h"
#include "thing.h"
#define TAG "beken_rtc"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
@ -23,7 +23,7 @@
void _rtc_websocket_audio_receive_data(rtc_session *rtc_session, uint8 *data, uint32_t len, rtc_user_audio_rx_data_handle_cb cb);
#define DEBUG_CRC
#define BEKEN_RTC_TXT_SIZE 500
#define BEKEN_RTC_TXT_SIZE 1024
static const uint8 crc8_table[256] =
{
0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
@ -825,7 +825,7 @@ int rtc_websocket_send_text(transport web_socket, void *str, enum MsgType msgtyp
break;
}
case BEKEN_RTC_SEND_LISTEN:{
// 创建主 JSON 对象
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> JSON <20><><EFBFBD><EFBFBD>
cJSON *listenMessage = cJSON_CreateObject();
if (listenMessage == NULL) {
@ -838,13 +838,13 @@ int rtc_websocket_send_text(transport web_socket, void *str, enum MsgType msgtyp
cJSON_AddStringToObject(listenMessage, "state", "detect");
cJSON_AddStringToObject(listenMessage, "mode", "auto");
cJSON_AddStringToObject(listenMessage, "text", "小美同学");
cJSON_AddStringToObject(listenMessage, "text", "С<EFBFBD><EFBFBD>ͬѧ");
// 将 cJSON 对象转换为字符串
// <EFBFBD><EFBFBD> cJSON <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
char *jsonString = cJSON_Print(listenMessage);
BK_LOGE("WebSocket", "Sending: %s\r\n", jsonString);
websocket_client_send_text(web_socket, jsonString, strlen(jsonString), 10*1000);
// 删除 cJSON 对象以释放内存
// ɾ<EFBFBD><EFBFBD> cJSON <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
cJSON_Delete(listenMessage);
break;
}
@ -857,19 +857,19 @@ int rtc_websocket_send_text(transport web_socket, void *str, enum MsgType msgtyp
// bk_printf("Global session_id_BEKEN_RTC_SEND_START_LISTEN: %s\n", session_id);
// 添加session_id字段
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>session_id<EFBFBD>ֶ<EFBFBD>
cJSON_AddStringToObject(startlistent, "session_id", "");
// 添加type字段
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>type<EFBFBD>ֶ<EFBFBD>
cJSON_AddStringToObject(startlistent, "type", "listen");
// 添加state字段
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>state<EFBFBD>ֶ<EFBFBD>
cJSON_AddStringToObject(startlistent, "state", "start");
// 添加mode字段
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>mode<EFBFBD>ֶ<EFBFBD>
cJSON_AddStringToObject(startlistent, "mode", "auto") ;
// 生成JSON字符串
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>JSON<EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD>
char *jsonString = cJSON_Print(startlistent);
websocket_client_send_text(web_socket, jsonString, strlen(jsonString), 10*1000);
@ -885,19 +885,19 @@ int rtc_websocket_send_text(transport web_socket, void *str, enum MsgType msgtyp
// bk_printf("Global session_id_BEKEN_RTC_SEND_STOP_LISTEN: %s\n", session_id);
// 添加session_id字段
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>session_id<EFBFBD>ֶ<EFBFBD>
cJSON_AddStringToObject(stoplistent, "session_id", "");
// 添加type字段
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>type<EFBFBD>ֶ<EFBFBD>
cJSON_AddStringToObject(stoplistent, "type", "listen");
// 添加state字段
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>state<EFBFBD>ֶ<EFBFBD>
cJSON_AddStringToObject(stoplistent, "state", "stop");
// 添加mode字段
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>mode<EFBFBD>ֶ<EFBFBD>
cJSON_AddStringToObject(stoplistent, "mode", "auto") ;
// 生成JSON字符串
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>JSON<EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD>
char *jsonString = cJSON_Print(stoplistent);
websocket_client_send_text(web_socket, jsonString, strlen(jsonString), 10*1000);
@ -906,79 +906,79 @@ int rtc_websocket_send_text(transport web_socket, void *str, enum MsgType msgtyp
}
case BEKEN_RTC_SEND_START:{
// 创建主 JSON 对象
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> JSON <20><><EFBFBD><EFBFBD>
cJSON *startMessage = cJSON_CreateObject();
if (startMessage == NULL) {
}
// 添加 "type" 字段
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> "type" <20>ֶ<EFBFBD>
cJSON_AddStringToObject(startMessage, "type", "start");
// 添加 "mode" 字段
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> "mode" <20>ֶ<EFBFBD>
cJSON_AddStringToObject(startMessage, "mode", "auto");
// 创建 "audio_params" JSON 对象
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> "audio_params" JSON <20><><EFBFBD><EFBFBD>
cJSON *audio_params = cJSON_CreateObject();
if (audio_params == NULL) {
cJSON_Delete(startMessage);
}
// 向 "audio_params" 添加字段
// <EFBFBD><EFBFBD> "audio_params" <20><><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>
cJSON_AddStringToObject(audio_params, "format", "opus");
cJSON_AddNumberToObject(audio_params, "sample_rate", 16000);
cJSON_AddNumberToObject(audio_params, "channels", 1);
cJSON_AddNumberToObject(audio_params, "frame_duration", 60);
// 将 "audio_params" 添加到主 JSON 对象
// <EFBFBD><EFBFBD> "audio_params" <20><><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD> JSON <20><><EFBFBD><EFBFBD>
cJSON_AddItemToObject(startMessage, "audio_params", audio_params);
// 将 cJSON 对象转换为字符串
// <EFBFBD><EFBFBD> cJSON <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
char *jsonString = cJSON_Print(startMessage);
BK_LOGE("WebSocket", "Sending: %s\r\n", jsonString);
websocket_client_send_text(web_socket, jsonString, strlen(jsonString), 10*1000);
// 删除 cJSON 对象以释放内存
// ɾ<EFBFBD><EFBFBD> cJSON <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
cJSON_Delete(startMessage);
break;}
case BEKEN_RTC_SEND_HELLO:{
// 创建主 JSON 对象
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> JSON <20><><EFBFBD><EFBFBD>
cJSON *helloMessage = cJSON_CreateObject();
if (helloMessage == NULL) {
//return NULL;
}
// 添加 "type" 字段
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> "type" <20>ֶ<EFBFBD>
cJSON_AddStringToObject(helloMessage, "type", "hello");
// 添加 "version" 字段
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> "version" <20>ֶ<EFBFBD>
cJSON_AddNumberToObject(helloMessage, "version", 3);
// 添加 "transport" 字段
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> "transport" <20>ֶ<EFBFBD>
cJSON_AddStringToObject(helloMessage, "transport", "websocket");
// 创建 "audio_params" JSON 对象
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> "audio_params" JSON <20><><EFBFBD><EFBFBD>
cJSON *audio_params = cJSON_CreateObject();
if (audio_params == NULL) {
cJSON_Delete(helloMessage);
//return NULL;
}
// 向 "audio_params" 添加字段
// <EFBFBD><EFBFBD> "audio_params" <20><><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>
cJSON_AddStringToObject(audio_params, "format", "opus");
cJSON_AddNumberToObject(audio_params, "sample_rate", 16000);
cJSON_AddNumberToObject(audio_params, "channels", 1);
cJSON_AddNumberToObject(audio_params, "frame_duration", 60);
// 将 "audio_params" 添加到主 JSON 对象
// <EFBFBD><EFBFBD> "audio_params" <20><><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD> JSON <20><><EFBFBD><EFBFBD>
cJSON_AddItemToObject(helloMessage, "audio_params", audio_params);
// 将 cJSON 对象转换为字符串
// <EFBFBD><EFBFBD> cJSON <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
char *jsonString = cJSON_Print(helloMessage);
BK_LOGE("WebSocket", "Sending: %s\r\n", jsonString);
websocket_client_send_text(web_socket, jsonString, strlen(jsonString), 10*1000);
// 删除 cJSON 对象以释放内存
// ɾ<EFBFBD><EFBFBD> cJSON <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
cJSON_Delete(helloMessage);
/*
@ -990,6 +990,21 @@ int rtc_websocket_send_text(transport web_socket, void *str, enum MsgType msgtyp
websocket_client_send_text(web_socket, buf, n, 10*1000);*/
break;}
case BEKEN_RTC_SEND_IOT_DESC:{
extern char *getGlobalSessionId(void);
cJSON* iot_desc = (cJSON*)thing_gen_iot_descriptors(getGlobalSessionId());
char *message = cJSON_PrintUnformatted(iot_desc);
if (message == NULL)
{
cJSON_Delete(iot_desc);
return -1;
}
LOGE("iot -->(len:%d) %s\n",strlen(message),message);
int ret = websocket_client_send_text(web_socket, message, strlen(message), 10*1000);
LOGE("send iot desc ret:%d \n",ret);
cJSON_Delete(iot_desc);
break;}
default:
BK_LOGE("WebSocket", "Unsupported message type");
return -1;

View File

@ -25,6 +25,8 @@ enum MsgType {
BEKEN_RTC_SEND_ABORT = 3,
BEKEN_RTC_SEND_STOP_LISTEN = 4,
BEKEN_RTC_SEND_START_LISTEN = 5,
BEKEN_RTC_SEND_IOT_DESC = 6,
};
/*
@ -134,6 +136,7 @@ void rtc_websocket_parse_text(text_info_t *text, cJSON *root);
void rtc_fill_audio_info(audio_info_t *info, char *type, uint32_t adc_rate, uint32_t dac_rate, uint32_t enc_ms, uint32_t dec_ms, uint32_t size);
int bk_rtc_video_data_send(const uint8_t *data_ptr, size_t data_len, const video_frame_info_t *info_ptr);
bk_err_t bk_rtc_register_video_rx_handle(rtc_video_rx_data_handle video_rx_handle);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,134 @@
#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 "iot_lamp.h"
#define TAG "iot_lamp"
#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__)
/*
[{
* "name": "Screen",
* "description": "这是小牛牛的灯光的亮度",
* "properties": {
* "theme": {
* "description": "主题",
* "type": "string"
* },
* "brightness": {
* "description": "当前亮度百分比",
* "type": "number"
* }},
* "methods": {
* "SetTheme": {
* "description": "设置屏幕主题",
* "parameters": {
* "theme_name": {
* "description": "主题模式, light 或 dark",
* "type": "string"
* }
* }
* },
* "SetBrightness": {
* "description": "设置亮度",
* "parameters": {
* "brightness": {
* "description": "0到100之间的整数",
* "type": "number"
* }
* }
* }
* }
* }]
*/
#define IOT_LAMP_DEVICE_NAME "lamp"
#define IOT_LAMP_DEVICE_FUNS_SET_BRIGHTNESS "SetBrightness"
cJSON* iot_lamp_get_device_desc(){
cJSON *lamp_desc = cJSON_CreateObject();
cJSON_AddStringToObject(lamp_desc, "name", IOT_LAMP_DEVICE_NAME);
cJSON_AddStringToObject(lamp_desc, "description", "这是小牛牛的灯光");
cJSON *properties = cJSON_CreateObject();
//定义brightness 属性
cJSON *brightness = cJSON_CreateObject();
cJSON_AddStringToObject(brightness, "description", "当前亮度百分比");
cJSON_AddStringToObject(brightness, "type", "number");
//添加brightness属性到properties
cJSON_AddItemToObjectCS(properties,"brightness",brightness);
//添加properties 到lamp_desc 描述
cJSON_AddItemToObjectCS(lamp_desc,"properties",properties);
//定义方法methods
cJSON *methods = cJSON_CreateObject();
//定义一个设置亮度的方法
/*"SetBrightness": {
"description": "设置亮度",
"parameters": {
"brightness": {
"description": "0到100之间的整数",
"type": "number"
}
}
}
*/
cJSON *SetBrightness = cJSON_CreateObject();
cJSON_AddStringToObject(SetBrightness, "description", "设置亮度");
cJSON *parameters = cJSON_CreateObject();
cJSON *p_brightness = cJSON_CreateObject();
cJSON_AddStringToObject(p_brightness, "type", "number");
cJSON_AddStringToObject(p_brightness, "description", "0到100之间的整数");
cJSON_AddItemToObjectCS(parameters,"brightness",p_brightness);
cJSON_AddItemToObjectCS(SetBrightness,"parameters",parameters);
//cJSON_AddStringToObject(SetBrightness, "type", "number");
cJSON_AddItemToObjectCS(methods,IOT_LAMP_DEVICE_FUNS_SET_BRIGHTNESS,SetBrightness);
cJSON_AddItemToObjectCS(lamp_desc,"methods",methods);
//打印一下描述
//char *json_desc = cJSON_Print(lamp_desc);
//LOGE("lamp_desc-->%s\n",json_desc);
//cJSON_Delete(lamp_desc);
return lamp_desc;
}
void iot_lamp_report_state(int brightness){
}
void iot_lamp_parser_invoke(char* cmd,char * paramters_json){
//设置亮度
if (strcmp(cmd, "SetBrightness") == 0)
{
//获取亮度值
cJSON* params = cJSON_Parse(paramters_json);
if(params == NULL) return;
// {"brightness": 60}
int brightness = cJSON_GetObjectItem(params, "brightness")->valueint;
LOGE("invoke brightness-->%d\n",brightness);
}
}

View File

@ -0,0 +1,26 @@
/*************************************************************
*
* Copyright (C) POKA
* All rights reserved.
*
*************************************************************/
#ifndef __IOT_LAMP_H__
#define __IOT_LAMP_H__
#ifdef __cplusplus
extern "C" {
#endif
//#include <stdbool.h>
//#include "beken_config.h"
//#include "bk_websocket_client.h"
#include "cJSON.h"
cJSON * iot_lamp_get_device_desc();
void iot_lamp_parser_invoke(char* cmd,char * paramters_json);
#ifdef __cplusplus
}
#endif
#endif /* __AGORA_RTC_H__ */

View File

@ -0,0 +1,223 @@
#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 "iot_speaker.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
#include "motor.h"
#endif
#define TAG "iot_speaker"
#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__)
#if (CONFIG_SYS_CPU0)
static uint32_t volume = 7; // volume level, not gain.
static uint32_t g_volume_gain[SPK_VOLUME_LEVEL] = {0, 0x05, 0x18, 0x10, 0x13, 0x15, 0x18, 0x21, 0x22, 0x25, 0x30};
void speaker_volume_init(void)
{
int volume_size = bk_config_read("volume", (void *)&volume, 4);
if (volume_size != 4)
{
BK_LOGE(TAG, "read volume config fail, use default config volume_size:%d\n", volume_size);
}
if (volume > (SPK_VOLUME_LEVEL - 1))
{
volume = SPK_VOLUME_LEVEL - 1;
if (0 != bk_config_write("volume", (void *)&volume, 4))
{
BK_LOGE(TAG, "storage volume: %d fail\n", volume);
}
}
/* SPK_GAIN_MAX * [(exp(i/(SPK_VOLUME_LEVEL-1)-1)/(exp(1)-1)] */
//uint32_t step[SPK_VOLUME_LEVEL] = {0, 6, 12, 20, 28, 37, 47, 58, 71, 84, 100};
//for (uint32_t i = 0; i < SPK_VOLUME_LEVEL; i++)
//{
//g_volume_gain[i] = SPK_GAIN_MAX * step[i] / 100;
//BK_LOGE(TAG, "g_volume_gain: %02X \n", g_volume_gain[i]);
//}
}
void speaker_volume_increase()
{
BK_LOGI(TAG, " volume up\r\n");
if (volume == (SPK_VOLUME_LEVEL - 1))
{
BK_LOGI(TAG, "volume have reached maximum volume: %d\n", SPK_GAIN_MAX);
return;
}
if (BK_OK == bk_aud_intf_set_spk_gain(g_volume_gain[volume + 1]))
{
volume += 1;
if (0 != bk_config_write("volume", (void *)&volume, 4))
{
BK_LOGE(TAG, "storage volume: %d fail\n", volume);
}
BK_LOGI(TAG, "current volume: %d\n", volume);
}
else
{
BK_LOGI(TAG, "set volume fail\n");
}
}
void speaker_volume_decrease()
{
BK_LOGI(TAG, " volume down\r\n");
if (volume == 0)
{
BK_LOGI(TAG, "volume have reached minimum volume: 0\n");
return;
}
if (BK_OK == bk_aud_intf_set_spk_gain(g_volume_gain[volume - 1]))
{
volume -= 1;
if (0 != bk_config_write("volume", (void *)&volume, 4))
{
BK_LOGE(TAG, "storage volume: %d fail\n", volume);
}
BK_LOGI(TAG, "current volume: %d\n", volume);
}
else
{
BK_LOGI(TAG, "set volume fail\n");
}
}
void speaker_volume_set_abs(uint8_t level, uint8_t has_precision)
{
bk_err_t ret = 0;
BK_LOGI(TAG, "%s volume abs %d %d\n", __func__, level, has_precision);
if (level > SPK_VOLUME_LEVEL - 1)
{
BK_LOGE(TAG, "%s invalid level %d >= %d\n", __func__, level, SPK_VOLUME_LEVEL);
level = SPK_VOLUME_LEVEL - 1;
}
if (level == 0 && has_precision)
{
BK_LOGW(TAG, "%s set raw gain 2 because precision\n", __func__);
ret = bk_aud_intf_set_spk_gain(2);
}
else
{
ret = bk_aud_intf_set_spk_gain(g_volume_gain[level]);
}
if (BK_OK == ret)
{
volume = level;
if (0 != bk_config_write("volume", (void *)&volume, sizeof(volume)))
{
BK_LOGE(TAG, "%s storage volume: %d fail\n", __func__, level);
}
BK_LOGI(TAG, "%s current volume: %d\n", __func__, level);
}
else
{
BK_LOGE(TAG, "%s set volume %d fail\n", __func__, level);
}
}
uint32_t speaker_volume_get_current()
{
return volume;
}
uint32_t speaker_volume_get_level_count()
{
return SPK_VOLUME_LEVEL;
}
#endif
cJSON* iot_speaker_get_device_desc()
{
cJSON *speaker_desc = cJSON_CreateObject();
cJSON_AddStringToObject(speaker_desc, "name", "speaker");
cJSON_AddStringToObject(speaker_desc, "description", "扬声器 音量调节");
cJSON *properties = cJSON_CreateObject();
//volume 属性
cJSON *volume = cJSON_CreateObject();
cJSON_AddStringToObject(volume, "description", "当前设备音量");
cJSON_AddStringToObject(volume, "type", "number");
//添加brightness属性到properties
cJSON_AddItemToObjectCS(properties,"volume",volume);
//添加properties speaker_desc 描述
cJSON_AddItemToObjectCS(speaker_desc,"properties",properties);
//定义方法methods
cJSON *methods = cJSON_CreateObject();
cJSON *setVolume = cJSON_CreateObject();
cJSON_AddStringToObject(setVolume, "description", "设置音量");
cJSON *parameters = cJSON_CreateObject();
cJSON *p_volume = cJSON_CreateObject();
cJSON_AddStringToObject(p_volume, "type", "number");
cJSON_AddStringToObject(p_volume, "description", "0到100之间的整数");
cJSON_AddItemToObjectCS(parameters,"volume",p_volume);
cJSON_AddItemToObjectCS(setVolume,"parameters",parameters);
//cJSON_AddStringToObject(SetBrightness, "type", "number");
cJSON_AddItemToObjectCS(methods,"setVolume",setVolume);
cJSON_AddItemToObjectCS(speaker_desc,"methods",methods);
//打印一下描述
//char *json_desc = cJSON_Print(speaker_desc);
//LOGE("speaker_desc-->%s\n",json_desc);
//cJSON_Delete(speaker_desc);
return speaker_desc;
}
void iot_speaker_parser_invoke(char* cmd,char * paramters_json){
LOGE("iot_speaker_parser_invoke :%s\n",paramters_json);
//设置音量
if (strcmp(cmd, "setVolume") == 0)
{
//获取亮度值
cJSON* params = cJSON_Parse(paramters_json);
if(params == NULL){
LOGE("params == NULL\n");
return;
}
// {"volume": 60}
int volume = cJSON_GetObjectItem(params, "volume")->valueint;
LOGE("volume :%d\n",volume);
if(volume > 10){
int level = volume/10;
LOGE("speaker_setVolume--> volume :%d level:%d\n",volume,level);
speaker_volume_set_abs(level,0);
}
}
}

View File

@ -0,0 +1,15 @@
#ifndef __IOT_SPEAKER_H__
#define __IOT_SPEAKER_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "cJSON.h"
void speaker_volume_init();
cJSON* iot_speaker_get_device_desc();
void iot_speaker_parser_invoke(char* cmd,char * paramters_json);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,72 @@
/**
* IoT设备相关消息
*
{
"session_id": "<会话ID>",
"type": "iot",
"descriptors": <设备描述JSON>
}
{
"session_id": "<会话ID>",
"type": "iot",
"states": <状态JSON>
}
/**
* descriptorMessage的json串
* [{
* "name": "Screen",
* "description": "这是一个屏幕,可设置主题和亮度",
* "properties": {
* "theme": {
* "description": "主题",
* "type": "string"
* },
* "brightness": {
* "description": "当前亮度百分比",
* "type": "number"
* }},
* "methods": {
* "SetTheme": {
* "description": "设置屏幕主题",
* "parameters": {
* "theme_name": {
* "description": "主题模式, light 或 dark",
* "type": "string"
* }
* }
* },
* "SetBrightness": {
* "description": "设置亮度",
* "parameters": {
* "brightness": {
* "description": "0到100之间的整数",
* "type": "number"
* }
* }
* }
* }
* }]
*
*
* statesMessage的json串
* [
* {
* "name": "Speaker",
* "state": {
* "volume": 70
* }
* },
* {
* "name": "Screen",
* "state": {
* "theme": "dark",
* "brightness": 75
* }
* }
* ]
*
* @throws Exception
*/

View File

@ -0,0 +1,121 @@
#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"
#define TAG "thing"
#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__)
/**
* IOT
*/
void thing_init()
{
#ifdef IOT_SPEAKER
speaker_volume_init();
#endif
}
cJSON* thing_gen_iot_descriptors(char *session_id)
{
// 1.判断数据合法
// 2.发送给服务器
cJSON *messageRoot = cJSON_CreateObject();
cJSON_AddStringToObject(messageRoot, "session_id", session_id);
cJSON_AddStringToObject(messageRoot, "type", "iot");
cJSON_AddBoolToObject(messageRoot, "update", true);
cJSON *descriptorArray = cJSON_CreateArray();
#ifdef IOT_LAMP
cJSON* lamp_desc = iot_lamp_get_device_desc();
//cJSON_AddItemToArray(descriptorArray, cJSON_Duplicate(descriptor, 1));
cJSON_AddItemToArray(descriptorArray, lamp_desc);
#endif
#ifdef IOT_SPEAKER
cJSON* speaker_desc = iot_speaker_get_device_desc();
//cJSON_AddItemToArray(descriptorArray, cJSON_Duplicate(descriptor, 1));
cJSON_AddItemToArray(descriptorArray, speaker_desc);
#endif
cJSON_AddItemToObject(messageRoot, "descriptors", descriptorArray);
return messageRoot;
}
/**
* IOT指令,
* :
*
* {
"type": "iot",
"commands": [
{
"name": "lamp",
"method": "SetBrightness",
"parameters": {
"brightness": 50
}
}
]
}
*/
void thing_iot_invoke(char *iot_json){
cJSON* iot_invoke = cJSON_Parse(iot_json);
cJSON *commands = cJSON_GetObjectItem(iot_invoke, "commands");
// 检查是否为数组类型
if (commands ==NULL && !cJSON_IsArray(commands)) {
cJSON_Delete(iot_invoke);
return ;
}
// 遍历数组并打印元素
int arraySize = cJSON_GetArraySize(commands);
for (int i = 0; i < arraySize; i++) {
cJSON *item = cJSON_GetArrayItem(commands, i);
char *name = cJSON_GetObjectItem(item, "name")->valuestring;
char *method = cJSON_GetObjectItem(item, "method")->valuestring;
cJSON *parameters = cJSON_GetObjectItem(item, "parameters");
char *str_parameters =cJSON_PrintUnformatted(parameters);
LOGE("cmd:%s method:%s\n",name,method);
//灯光指令
if (strcmp(name, "lamp") == 0)
{
iot_lamp_parser_invoke(method,str_parameters);
}
//扬声器指令
if (strcmp(name, "speaker") == 0)
{
iot_speaker_parser_invoke(method,str_parameters);
}
}
// 释放内存
cJSON_Delete(iot_invoke);
}
// AddStringProperty
// AddNumberProperty
// AddBooleanProperty
// AddMethod

View File

@ -0,0 +1,51 @@
#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"
#define IOT_LAMP 1
#define IOT_SPEAKER 1
#define IOT_SLEEP_HELPER 1
void thing_init();
cJSON * thing_create(char * name,char *description);
/*
"theme": {
"description": "主题",
"type": "string"
},*/
cJSON * thing_add_string_property(char * name,char *description);
/*
"theme": {
"description": "主题",
"type": "string"
},*/
cJSON * thing_add_number_property(char * name,char *description);
//AddStringProperty
//AddNumberProperty
//AddBooleanProperty
//AddMethod
/**
* IOT
*/
cJSON* thing_gen_iot_descriptors(char *session_id);
/**
* IOT指令,
*/
void thing_iot_invoke(char *iot_json);

View File

@ -32,6 +32,8 @@
#include "app_event.h"
#include "cJSON.h"
#include "audio_process.h"
#include "thing.h"
#define TAG "WS_MAIN"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
@ -542,12 +544,22 @@ void rtc_websocket_msg_handle(char *json_text, unsigned int size)
app_event_send_msg(APP_EVT_AGENT_JOINED, 0);
smart_config_running = false;
__get_beken_rtc()->disconnecting_state = 0;
//发送设备IOT能力描述到服务器
//rtc_websocket_send_text(client, "", BEKEN_RTC_SEND_IOT_DESC);
}
else
{
LOGE("join WebSocket server fail\r\n");
}
}
//解析服务器下发的IOT 指令
else if (strcmp(type->valuestring, "iot") == 0)
{
thing_iot_invoke(json_text);
}
// else if ((strcmp(type->valuestring, "reply_text") == 0) || (strcmp(type->valuestring, "request_text") == 0)) {
// text_info_t info = {0};
// info.text_type = (strcmp(type->valuestring, "request_text") == 0) ? 0:1;
@ -662,7 +674,7 @@ void sent_abort_msg()
first_abort = 1;
return;
}
// bk_printf("MEDIA_APP_EVT_ASR_WAKEUP_IND_sent_abort_msg first_abort = %d\n",first_abort);
// bk_printf("MEDIA_APP_EVT_ASR_WAKEUP_IND_sent_abort_msg first_abort = %d\n",first_abort);
if (client)
{
bk_printf("rtc_websocket_send_text_BEKEN_RTC_SEND_ABORT_BEKEN_RTC_SEND_STOP_LISTEN_BEKEN_RTC_SEND_START_LISTEN\r\n");
@ -676,6 +688,7 @@ void sent_abort_msg()
}
}
// 检查二进制数据接收状态的接口函数
uint8_t get_binary_data_status(void)
{
@ -748,6 +761,9 @@ void rtc_websocket_event_handler(void *event_handler_arg, char *event_base, int3
rtc_websocket_send_text(client, (void *)(&audio_info), BEKEN_RTC_SEND_HELLO);
rtos_delay_milliseconds(100);
rtc_websocket_send_text(client, (void *)(&audio_info), BEKEN_RTC_SEND_START);
rtos_delay_milliseconds(100);
rtc_websocket_send_text(client, (void *)(&audio_info), BEKEN_RTC_SEND_IOT_DESC);
// rtc_websocket_send_text(client, (void *)(&audio_info), BEKEN_RTC_SEND_START_LISTEN);
// rtos_delay_milliseconds(200);
// rtc_websocket_send_text(client, (void *)(&audio_info), BEKEN_RTC_SEND_LISTEN);
@ -799,8 +815,8 @@ void beken_rtc_main(void)
bk_printf("headers = %s\r\n", headers);
websocket_cfg.headers = headers;
websocket_cfg.uri = "wss://xiaozhi.xa-poka.com/websocket/xiaozhi/v1/";
// websocket_cfg.uri = "ws://43.139.216.160:8000/xiaozhi/v1/";
//websocket_cfg.uri = "wss://xiaozhi.xa-poka.com/websocket/xiaozhi/v1/";
websocket_cfg.uri = "ws://43.139.216.160:8000/xiaozhi/v1/";
websocket_cfg.ws_event_handler = rtc_websocket_event_handler;
rtc_session *rtc_session = rtc_websocket_create(&websocket_cfg, rtc_user_audio_rx_data_handle, &audio_info);
if (rtc_session == NULL)