mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-28 01:53:53 +08:00
update:优化无用组件
This commit is contained in:
+27
-23
@@ -1,16 +1,28 @@
|
|||||||
package xiaozhi.modules.sys.controller;
|
package xiaozhi.modules.sys.controller;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.socket.WebSocketHttpHeaders;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
import org.springframework.web.socket.WebSocketHttpHeaders;
|
|
||||||
import xiaozhi.common.annotation.LogOperation;
|
import xiaozhi.common.annotation.LogOperation;
|
||||||
import xiaozhi.common.constant.Constant;
|
import xiaozhi.common.constant.Constant;
|
||||||
import xiaozhi.common.exception.RenException;
|
import xiaozhi.common.exception.RenException;
|
||||||
@@ -22,11 +34,6 @@ import xiaozhi.modules.sys.enums.ServerActionEnum;
|
|||||||
import xiaozhi.modules.sys.service.SysParamsService;
|
import xiaozhi.modules.sys.service.SysParamsService;
|
||||||
import xiaozhi.modules.sys.utils.WebSocketClientManager;
|
import xiaozhi.modules.sys.utils.WebSocketClientManager;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 服务端管理控制器
|
* 服务端管理控制器
|
||||||
*/
|
*/
|
||||||
@@ -34,11 +41,10 @@ import java.util.concurrent.TimeUnit;
|
|||||||
@RequestMapping("admin/server")
|
@RequestMapping("admin/server")
|
||||||
@Tag(name = "服务端管理")
|
@Tag(name = "服务端管理")
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class ServerSideManageController
|
public class ServerSideManageController {
|
||||||
{
|
|
||||||
private final SysParamsService sysParamsService;
|
private final SysParamsService sysParamsService;
|
||||||
private static final ObjectMapper objectMapper;
|
private static final ObjectMapper objectMapper;
|
||||||
static {
|
static {
|
||||||
objectMapper = new ObjectMapper();
|
objectMapper = new ObjectMapper();
|
||||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
}
|
}
|
||||||
@@ -54,7 +60,7 @@ public class ServerSideManageController
|
|||||||
@Operation(summary = "通知python服务端更新配置")
|
@Operation(summary = "通知python服务端更新配置")
|
||||||
@PostMapping("/emit-action")
|
@PostMapping("/emit-action")
|
||||||
@LogOperation("通知python服务端更新配置")
|
@LogOperation("通知python服务端更新配置")
|
||||||
// @RequiresPermissions("sys:role:superAdmin")
|
@RequiresPermissions("sys:role:superAdmin")
|
||||||
public Result<Boolean> emitServerAction(@RequestBody @Valid EmitSeverActionDTO emitSeverActionDTO) {
|
public Result<Boolean> emitServerAction(@RequestBody @Valid EmitSeverActionDTO emitSeverActionDTO) {
|
||||||
if (emitSeverActionDTO.getAction() == null) {
|
if (emitSeverActionDTO.getAction() == null) {
|
||||||
throw new RenException("无效服务端操作");
|
throw new RenException("无效服务端操作");
|
||||||
@@ -78,8 +84,8 @@ public class ServerSideManageController
|
|||||||
}
|
}
|
||||||
String serverSK = sysParamsService.getValue(Constant.SERVER_SECRET, true);
|
String serverSK = sysParamsService.getValue(Constant.SERVER_SECRET, true);
|
||||||
WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
|
WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
|
||||||
headers.add("Authorization", "Bearer " + serverSK);
|
headers.add("device-id", UUID.randomUUID().toString());
|
||||||
headers.add("device-id", serverSK);
|
headers.add("client-id", UUID.randomUUID().toString());
|
||||||
|
|
||||||
try (WebSocketClientManager client = new WebSocketClientManager.Builder()
|
try (WebSocketClientManager client = new WebSocketClientManager.Builder()
|
||||||
.connectTimeout(3, TimeUnit.SECONDS)
|
.connectTimeout(3, TimeUnit.SECONDS)
|
||||||
@@ -91,22 +97,20 @@ public class ServerSideManageController
|
|||||||
client.sendJson(
|
client.sendJson(
|
||||||
ServerActionPayloadDTO.build(
|
ServerActionPayloadDTO.build(
|
||||||
actionEnum,
|
actionEnum,
|
||||||
Map.of("secret", serverSK)
|
Map.of("secret", serverSK)));
|
||||||
));
|
|
||||||
// 等待服务端响应并持续监听信息
|
// 等待服务端响应并持续监听信息
|
||||||
client.listener((jsonText)-> {
|
client.listener((jsonText) -> {
|
||||||
if (StringUtils.isBlank(jsonText)) {
|
if (StringUtils.isBlank(jsonText)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return ServerActionResponseDTO.isSuccess(objectMapper.readValue(jsonText, ServerActionResponseDTO.class));
|
return ServerActionResponseDTO
|
||||||
}
|
.isSuccess(objectMapper.readValue(jsonText, ServerActionResponseDTO.class));
|
||||||
catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
// 捕获全部错误,由全局异常处理器返回
|
// 捕获全部错误,由全局异常处理器返回
|
||||||
throw new RenException("WebSocket连接失败或连接超时");
|
throw new RenException("WebSocket连接失败或连接超时");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="welcome">
|
<div class="welcome">
|
||||||
<HeaderBar/>
|
<HeaderBar />
|
||||||
|
|
||||||
<div class="operation-bar">
|
<div class="operation-bar">
|
||||||
<h2 class="page-title">服务端管理</h2>
|
<h2 class="page-title">服务端管理</h2>
|
||||||
<div class="right-operations">
|
|
||||||
<el-input placeholder="请输入服务端ws地址查询" v-model="searchCode" class="search-input"
|
|
||||||
@keyup.enter.native="handleSearch" clearable/>
|
|
||||||
<el-button class="btn-search" @click="handleSearch">搜索</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
@@ -16,9 +11,8 @@
|
|||||||
<div class="content-area">
|
<div class="content-area">
|
||||||
<el-card class="params-card" shadow="never">
|
<el-card class="params-card" shadow="never">
|
||||||
<el-table ref="paramsTable" :data="paramsList" class="transparent-table" v-loading="loading"
|
<el-table ref="paramsTable" :data="paramsList" class="transparent-table" v-loading="loading"
|
||||||
element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading"
|
element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading"
|
||||||
element-loading-background="rgba(255, 255, 255, 0.7)"
|
element-loading-background="rgba(255, 255, 255, 0.7)" :header-cell-class-name="headerCellClassName">
|
||||||
:header-cell-class-name="headerCellClassName">
|
|
||||||
<el-table-column label="选择" align="center" width="120">
|
<el-table-column label="选择" align="center" width="120">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-checkbox v-model="scope.row.selected"></el-checkbox>
|
<el-checkbox v-model="scope.row.selected"></el-checkbox>
|
||||||
@@ -28,34 +22,11 @@
|
|||||||
<el-table-column label="操作" prop="operator" align="center" show-overflow-tooltip>
|
<el-table-column label="操作" prop="operator" align="center" show-overflow-tooltip>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button size="medium" type="text" @click="emitAction(scope.row, actionMap.restart)">重启</el-button>
|
<el-button size="medium" type="text" @click="emitAction(scope.row, actionMap.restart)">重启</el-button>
|
||||||
<el-button size="medium" type="text" @click="emitAction(scope.row, actionMap.update_config)">更新配置</el-button>
|
<el-button size="medium" type="text"
|
||||||
|
@click="emitAction(scope.row, actionMap.update_config)">更新配置</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div class="table_bottom">
|
|
||||||
<div class="custom-pagination">
|
|
||||||
<el-select v-model="pageSize" @change="handlePageSizeChange" class="page-size-select">
|
|
||||||
<el-option v-for="item in pageSizeOptions" :key="item" :label="`${item}条/页`"
|
|
||||||
:value="item">
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
<button class="pagination-btn" :disabled="currentPage === 1" @click="goFirst">
|
|
||||||
首页
|
|
||||||
</button>
|
|
||||||
<button class="pagination-btn" :disabled="currentPage === 1" @click="goPrev">
|
|
||||||
上一页
|
|
||||||
</button>
|
|
||||||
<button v-for="page in visiblePages" :key="page" class="pagination-btn"
|
|
||||||
:class="{ active: page === currentPage }" @click="goToPage(page)">
|
|
||||||
{{ page }}
|
|
||||||
</button>
|
|
||||||
<button class="pagination-btn" :disabled="currentPage === pageCount" @click="goNext">
|
|
||||||
下一页
|
|
||||||
</button>
|
|
||||||
<span class="total-text">共{{ total }}条记录</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -63,7 +34,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<el-footer>
|
<el-footer>
|
||||||
<version-footer/>
|
<version-footer />
|
||||||
</el-footer>
|
</el-footer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -75,10 +46,9 @@ import ParamDialog from "@/components/ParamDialog.vue";
|
|||||||
import VersionFooter from "@/components/VersionFooter.vue";
|
import VersionFooter from "@/components/VersionFooter.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {HeaderBar, ParamDialog, VersionFooter},
|
components: { HeaderBar, ParamDialog, VersionFooter },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
searchCode: "",
|
|
||||||
paramsList: [],
|
paramsList: [],
|
||||||
actionMap: {
|
actionMap: {
|
||||||
restart: {
|
restart: {
|
||||||
@@ -144,25 +114,21 @@ export default {
|
|||||||
fetchParams() {
|
fetchParams() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
Api.admin.getWsServerList(
|
Api.admin.getWsServerList(
|
||||||
{},
|
{},
|
||||||
({data}) => {
|
({ data }) => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
if (data.code === 0) {
|
if (data.code === 0) {
|
||||||
this.paramsList = data.data.map(item => ({address: item}));
|
this.paramsList = data.data.map(item => ({ address: item }));
|
||||||
this.total = data.data.length;
|
this.total = data.data.length;
|
||||||
} else {
|
} else {
|
||||||
this.$message.error({
|
this.$message.error({
|
||||||
message: data.msg || '获取参数列表失败',
|
message: data.msg || '获取参数列表失败',
|
||||||
showClose: true
|
showClose: true
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
handleSearch() {
|
|
||||||
this.currentPage = 1;
|
|
||||||
this.fetchParams();
|
|
||||||
},
|
|
||||||
emitAction(rowItem, actionItem) {
|
emitAction(rowItem, actionItem) {
|
||||||
if (actionItem === undefined || rowItem.address === undefined) {
|
if (actionItem === undefined || rowItem.address === undefined) {
|
||||||
return;
|
return;
|
||||||
@@ -175,7 +141,7 @@ export default {
|
|||||||
Api.admin.sendWsServerAction({
|
Api.admin.sendWsServerAction({
|
||||||
targetWs: rowItem.address,
|
targetWs: rowItem.address,
|
||||||
action: actionItem.value
|
action: actionItem.value
|
||||||
}, ({data}) => {
|
}, ({ data }) => {
|
||||||
if (data.code !== 0) {
|
if (data.code !== 0) {
|
||||||
this.$message.error({
|
this.$message.error({
|
||||||
message: data.msg || '操作失败',
|
message: data.msg || '操作失败',
|
||||||
@@ -190,31 +156,11 @@ export default {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
headerCellClassName({columnIndex}) {
|
headerCellClassName({ columnIndex }) {
|
||||||
if (columnIndex === 0) {
|
if (columnIndex === 0) {
|
||||||
return "custom-selection-header";
|
return "custom-selection-header";
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
},
|
|
||||||
goFirst() {
|
|
||||||
this.currentPage = 1;
|
|
||||||
this.fetchParams();
|
|
||||||
},
|
|
||||||
goPrev() {
|
|
||||||
if (this.currentPage > 1) {
|
|
||||||
this.currentPage--;
|
|
||||||
this.fetchParams();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
goNext() {
|
|
||||||
if (this.currentPage < this.pageCount) {
|
|
||||||
this.currentPage++;
|
|
||||||
this.fetchParams();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
goToPage(page) {
|
|
||||||
this.currentPage = page;
|
|
||||||
this.fetchParams();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -356,74 +302,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-pagination {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
|
|
||||||
.el-select {
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pagination-btn:first-child,
|
|
||||||
.pagination-btn:nth-child(2),
|
|
||||||
.pagination-btn:nth-last-child(2),
|
|
||||||
.pagination-btn:nth-child(3) {
|
|
||||||
min-width: 60px;
|
|
||||||
height: 32px;
|
|
||||||
padding: 0 12px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 1px solid #e4e7ed;
|
|
||||||
background: #dee7ff;
|
|
||||||
color: #606266;
|
|
||||||
font-size: 14px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: #d7dce6;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:disabled {
|
|
||||||
opacity: 0.6;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.pagination-btn:not(:first-child):not(:nth-child(3)):not(:nth-child(2)):not(:nth-last-child(2)) {
|
|
||||||
min-width: 28px;
|
|
||||||
height: 32px;
|
|
||||||
padding: 0;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
background: transparent;
|
|
||||||
color: #606266;
|
|
||||||
font-size: 14px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: rgba(245, 247, 250, 0.3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.pagination-btn.active {
|
|
||||||
background: #5f70f3 !important;
|
|
||||||
color: #ffffff !important;
|
|
||||||
border-color: #5f70f3 !important;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: #6d7cf5 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.total-text {
|
|
||||||
color: #909399;
|
|
||||||
font-size: 14px;
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.transparent-table) {
|
:deep(.transparent-table) {
|
||||||
background: white;
|
background: white;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@@ -490,7 +368,7 @@ export default {
|
|||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
& + tr {
|
&+tr {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ from core.utils.util import (
|
|||||||
initialize_modules,
|
initialize_modules,
|
||||||
check_vad_update,
|
check_vad_update,
|
||||||
check_asr_update,
|
check_asr_update,
|
||||||
|
filter_sensitive_info,
|
||||||
)
|
)
|
||||||
from concurrent.futures import ThreadPoolExecutor, TimeoutError
|
from concurrent.futures import ThreadPoolExecutor, TimeoutError
|
||||||
from core.handle.sendAudioHandle import sendAudioMessage
|
from core.handle.sendAudioHandle import sendAudioMessage
|
||||||
@@ -276,7 +277,7 @@ class ConnectionHandler:
|
|||||||
"type": "server",
|
"type": "server",
|
||||||
"status": "success",
|
"status": "success",
|
||||||
"message": "服务器重启中...",
|
"message": "服务器重启中...",
|
||||||
"content": {'action': "restart"}
|
"content": {"action": "restart"},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -306,7 +307,7 @@ class ConnectionHandler:
|
|||||||
"type": "server",
|
"type": "server",
|
||||||
"status": "error",
|
"status": "error",
|
||||||
"message": f"Restart failed: {str(e)}",
|
"message": f"Restart failed: {str(e)}",
|
||||||
'content': {'action': "restart"}
|
"content": {"action": "restart"},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -1089,37 +1090,3 @@ class ConnectionHandler:
|
|||||||
break
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.bind(tag=TAG).error(f"超时检查任务出错: {e}")
|
self.logger.bind(tag=TAG).error(f"超时检查任务出错: {e}")
|
||||||
|
|
||||||
|
|
||||||
def filter_sensitive_info(config: dict) -> dict:
|
|
||||||
"""
|
|
||||||
过滤配置中的敏感信息
|
|
||||||
Args:
|
|
||||||
config: 原始配置字典
|
|
||||||
Returns:
|
|
||||||
过滤后的配置字典
|
|
||||||
"""
|
|
||||||
sensitive_keys = [
|
|
||||||
"api_key",
|
|
||||||
"personal_access_token",
|
|
||||||
"access_token",
|
|
||||||
"token",
|
|
||||||
"secret",
|
|
||||||
"access_key_secret",
|
|
||||||
"secret_key",
|
|
||||||
]
|
|
||||||
|
|
||||||
def _filter_dict(d: dict) -> dict:
|
|
||||||
filtered = {}
|
|
||||||
for k, v in d.items():
|
|
||||||
if any(sensitive in k.lower() for sensitive in sensitive_keys):
|
|
||||||
filtered[k] = "***"
|
|
||||||
elif isinstance(v, dict):
|
|
||||||
filtered[k] = _filter_dict(v)
|
|
||||||
elif isinstance(v, list):
|
|
||||||
filtered[k] = [_filter_dict(i) if isinstance(i, dict) else i for i in v]
|
|
||||||
else:
|
|
||||||
filtered[k] = v
|
|
||||||
return filtered
|
|
||||||
|
|
||||||
return _filter_dict(copy.deepcopy(config))
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
from core.handle.abortHandle import handleAbortMessage
|
from core.handle.abortHandle import handleAbortMessage
|
||||||
from core.handle.helloHandle import handleHelloMessage
|
from core.handle.helloHandle import handleHelloMessage
|
||||||
from core.utils.util import remove_punctuation_and_length
|
from core.utils.util import remove_punctuation_and_length, filter_sensitive_info
|
||||||
from core.handle.receiveAudioHandle import startToChat, handleAudioMessage
|
from core.handle.receiveAudioHandle import startToChat, handleAudioMessage
|
||||||
from core.handle.sendAudioHandle import send_stt_message, send_tts_message
|
from core.handle.sendAudioHandle import send_stt_message, send_tts_message
|
||||||
from core.handle.iotHandle import handleIotDescriptors, handleIotStatus
|
from core.handle.iotHandle import handleIotDescriptors, handleIotStatus
|
||||||
@@ -13,17 +13,20 @@ TAG = __name__
|
|||||||
|
|
||||||
async def handleTextMessage(conn, message):
|
async def handleTextMessage(conn, message):
|
||||||
"""处理文本消息"""
|
"""处理文本消息"""
|
||||||
conn.logger.bind(tag=TAG).info(f"收到文本消息:{message}")
|
|
||||||
try:
|
try:
|
||||||
msg_json = json.loads(message)
|
msg_json = json.loads(message)
|
||||||
if isinstance(msg_json, int):
|
if isinstance(msg_json, int):
|
||||||
|
conn.logger.bind(tag=TAG).info(f"收到文本消息:{message}")
|
||||||
await conn.websocket.send(message)
|
await conn.websocket.send(message)
|
||||||
return
|
return
|
||||||
if msg_json["type"] == "hello":
|
if msg_json["type"] == "hello":
|
||||||
|
conn.logger.bind(tag=TAG).info(f"收到hello消息:{message}")
|
||||||
await handleHelloMessage(conn, msg_json)
|
await handleHelloMessage(conn, msg_json)
|
||||||
elif msg_json["type"] == "abort":
|
elif msg_json["type"] == "abort":
|
||||||
|
conn.logger.bind(tag=TAG).info(f"收到abort消息:{message}")
|
||||||
await handleAbortMessage(conn)
|
await handleAbortMessage(conn)
|
||||||
elif msg_json["type"] == "listen":
|
elif msg_json["type"] == "listen":
|
||||||
|
conn.logger.bind(tag=TAG).info(f"收到listen消息:{message}")
|
||||||
if "mode" in msg_json:
|
if "mode" in msg_json:
|
||||||
conn.client_listen_mode = msg_json["mode"]
|
conn.client_listen_mode = msg_json["mode"]
|
||||||
conn.logger.bind(tag=TAG).debug(
|
conn.logger.bind(tag=TAG).debug(
|
||||||
@@ -64,11 +67,16 @@ async def handleTextMessage(conn, message):
|
|||||||
# 否则需要LLM对文字内容进行答复
|
# 否则需要LLM对文字内容进行答复
|
||||||
await startToChat(conn, text)
|
await startToChat(conn, text)
|
||||||
elif msg_json["type"] == "iot":
|
elif msg_json["type"] == "iot":
|
||||||
|
conn.logger.bind(tag=TAG).info(f"收到iot消息:{message}")
|
||||||
if "descriptors" in msg_json:
|
if "descriptors" in msg_json:
|
||||||
asyncio.create_task(handleIotDescriptors(conn, msg_json["descriptors"]))
|
asyncio.create_task(handleIotDescriptors(conn, msg_json["descriptors"]))
|
||||||
if "states" in msg_json:
|
if "states" in msg_json:
|
||||||
asyncio.create_task(handleIotStatus(conn, msg_json["states"]))
|
asyncio.create_task(handleIotStatus(conn, msg_json["states"]))
|
||||||
elif msg_json["type"] == "server":
|
elif msg_json["type"] == "server":
|
||||||
|
# 记录日志时过滤敏感信息
|
||||||
|
conn.logger.bind(tag=TAG).info(
|
||||||
|
f"收到服务器消息:{filter_sensitive_info(msg_json)}"
|
||||||
|
)
|
||||||
# 如果配置是从API读取的,则需要验证secret
|
# 如果配置是从API读取的,则需要验证secret
|
||||||
if not conn.read_config_from_api:
|
if not conn.read_config_from_api:
|
||||||
return
|
return
|
||||||
@@ -98,7 +106,7 @@ async def handleTextMessage(conn, message):
|
|||||||
"type": "server",
|
"type": "server",
|
||||||
"status": "error",
|
"status": "error",
|
||||||
"message": "无法获取服务器实例",
|
"message": "无法获取服务器实例",
|
||||||
"content": {"action": "update_config"}
|
"content": {"action": "update_config"},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -111,7 +119,7 @@ async def handleTextMessage(conn, message):
|
|||||||
"type": "server",
|
"type": "server",
|
||||||
"status": "error",
|
"status": "error",
|
||||||
"message": "更新服务器配置失败",
|
"message": "更新服务器配置失败",
|
||||||
"content": {"action": "update_config"}
|
"content": {"action": "update_config"},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -124,7 +132,7 @@ async def handleTextMessage(conn, message):
|
|||||||
"type": "server",
|
"type": "server",
|
||||||
"status": "success",
|
"status": "success",
|
||||||
"message": "配置更新成功",
|
"message": "配置更新成功",
|
||||||
"content": {"action": "update_config"}
|
"content": {"action": "update_config"},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -136,7 +144,7 @@ async def handleTextMessage(conn, message):
|
|||||||
"type": "server",
|
"type": "server",
|
||||||
"status": "error",
|
"status": "error",
|
||||||
"message": f"更新配置失败: {str(e)}",
|
"message": f"更新配置失败: {str(e)}",
|
||||||
"content": {"action": "update_config"}
|
"content": {"action": "update_config"},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import opuslib_next
|
|||||||
from pydub import AudioSegment
|
from pydub import AudioSegment
|
||||||
from typing import Dict, Any
|
from typing import Dict, Any
|
||||||
from core.utils import tts, llm, intent, memory, vad, asr
|
from core.utils import tts, llm, intent, memory, vad, asr
|
||||||
|
import copy
|
||||||
|
|
||||||
TAG = __name__
|
TAG = __name__
|
||||||
emoji_map = {
|
emoji_map = {
|
||||||
@@ -319,7 +320,7 @@ def initialize_modules(
|
|||||||
modules["memory"] = memory.create_instance(
|
modules["memory"] = memory.create_instance(
|
||||||
memory_type,
|
memory_type,
|
||||||
config["Memory"][select_memory_module],
|
config["Memory"][select_memory_module],
|
||||||
config.get('summaryMemory', None),
|
config.get("summaryMemory", None),
|
||||||
)
|
)
|
||||||
logger.bind(tag=TAG).info(f"初始化组件: memory成功 {select_memory_module}")
|
logger.bind(tag=TAG).info(f"初始化组件: memory成功 {select_memory_module}")
|
||||||
|
|
||||||
@@ -956,3 +957,37 @@ def check_asr_update(before_config, new_config):
|
|||||||
)
|
)
|
||||||
update_asr = current_asr_type != new_asr_type
|
update_asr = current_asr_type != new_asr_type
|
||||||
return update_asr
|
return update_asr
|
||||||
|
|
||||||
|
|
||||||
|
def filter_sensitive_info(config: dict) -> dict:
|
||||||
|
"""
|
||||||
|
过滤配置中的敏感信息
|
||||||
|
Args:
|
||||||
|
config: 原始配置字典
|
||||||
|
Returns:
|
||||||
|
过滤后的配置字典
|
||||||
|
"""
|
||||||
|
sensitive_keys = [
|
||||||
|
"api_key",
|
||||||
|
"personal_access_token",
|
||||||
|
"access_token",
|
||||||
|
"token",
|
||||||
|
"secret",
|
||||||
|
"access_key_secret",
|
||||||
|
"secret_key",
|
||||||
|
]
|
||||||
|
|
||||||
|
def _filter_dict(d: dict) -> dict:
|
||||||
|
filtered = {}
|
||||||
|
for k, v in d.items():
|
||||||
|
if any(sensitive in k.lower() for sensitive in sensitive_keys):
|
||||||
|
filtered[k] = "***"
|
||||||
|
elif isinstance(v, dict):
|
||||||
|
filtered[k] = _filter_dict(v)
|
||||||
|
elif isinstance(v, list):
|
||||||
|
filtered[k] = [_filter_dict(i) if isinstance(i, dict) else i for i in v]
|
||||||
|
else:
|
||||||
|
filtered[k] = v
|
||||||
|
return filtered
|
||||||
|
|
||||||
|
return _filter_dict(copy.deepcopy(config))
|
||||||
|
|||||||
Reference in New Issue
Block a user