增加关键字支持

This commit is contained in:
wulin 2023-10-12 13:50:03 +08:00
parent af64a3caaa
commit e062a568ef
12 changed files with 150 additions and 103 deletions

View File

@ -19,7 +19,8 @@ public enum AskTypeEnum {
BOX_OFF_LINE(102, "Box离线"),
DEVICE_UNBIND(103, "设备解绑"),
DEVICE_BIND(104, "设备绑定成功"),
COMMAND_N(200, "指令后必须跟的名称词")
COMMAND_N(200, "指令后必须跟的名称词"),
QIU_GUO(300, "秋果专有名词")
;
AskTypeEnum(Integer c, String n){
code = c;

View File

@ -8,6 +8,7 @@ public enum KeyTypeEnum {
SYSTEM_COMMAND(0, "系统自定义名称关键字"),
USER_BIND_NAME(1, "用户绑定的设备名称"),
SYSTEM_ACTION(2, "系统自定义动作动词"),
QIUGUO_NAME(3, "秋果专有名称"),
;
KeyTypeEnum(Integer c, String n){
code = c;

View File

@ -8,4 +8,9 @@ public class TongYiCommunicationRest {
private String text;//消息
private String onlyId;//唯一编码
private String status; //状态,0:已完成,1.未发起,2.发起中
/**
* 请求序号
*/
private Long requestId = 0L;
}

View File

@ -51,22 +51,27 @@ public class SystemTalkAnswerConfigService extends GenericReactiveCrudService<Sy
*/
private static List<SystemTalkAnswerConfigEntity> groupCommand = new ArrayList<>();
@PostConstruct
public void initGroup() {
log.info("初始化自定义回答缓存数据");
group.clear();
groupCommand.clear();
ReactiveQuery<SystemTalkAnswerConfigEntity> reactiveQuery = createQuery();
reactiveQuery = reactiveQuery.and("is_delete", 0);
reactiveQuery.paging(0, MAX_COUT.intValue()).fetch().map(item ->{
if(item.getAnswerType() < AskTypeEnum.UPDATE.getCode()) {
group.put(item.getAskKey(), item);
}else if(item.getAnswerType().equals(AskTypeEnum.COMMAND_N.getCode())){
}else{
groupCommand.add(item);
}
return item;
}).doFinally(signalType -> {
log.info("配置最多读取{}条,实际读取了{}条自定义回答指令,指令后参数名称{}条", MAX_COUT, group.size(), groupCommand.size());
log.info("配置最多读取{}条,实际读取了{}条自定义回答指令,指令后参数名称{}条",
MAX_COUT,
group.size(),
groupCommand.size());
}).subscribeOn(Schedulers.single()).subscribe();
}

View File

@ -152,7 +152,7 @@ public enum ChinesePartSpeechEnum implements IChinesePartSpeech{
return nt.getAction(keyGroup, key, actions, action, systemTalkAnswerConfigEntities, includs, commands);
}
},
/*nz(5, "其他专名"){
nz(5, "其他专名"){
@Override
public Action getAction(ConcurrentHashMap<String, SystemTalkAnswerConfigEntity> keyGroup,
String key,
@ -161,9 +161,9 @@ public enum ChinesePartSpeechEnum implements IChinesePartSpeech{
List<SystemTalkAnswerConfigEntity> systemTalkAnswerConfigEntities,
List<DeviceUserBindEntity> includs,
List<SystemTalkAnswerConfigEntity> commands){
return action;
return n.getAction(keyGroup, key, actions, action, systemTalkAnswerConfigEntities, includs, commands);
}
},*/
},
n(6, "名词"){
@Override
public Action getAction(ConcurrentHashMap<String, SystemTalkAnswerConfigEntity> keyGroup,
@ -708,14 +708,25 @@ public enum ChinesePartSpeechEnum implements IChinesePartSpeech{
List<SystemTalkAnswerConfigEntity> commands){
//动词后面的名词只支持已经产生的action后面的不要
int index = Integer.parseInt(key.replace("#", ""));
action.setActionCommand(commands.get(index).getAskKey());
for (Action ac: actions.getActions()
) {
if(!StringUtils.isNotEmpty(ac.getActionCommand())){
ac.setActionCommand(action.getActionCommand());
SystemTalkAnswerConfigEntity command = commands.get(index);
if(command.getAnswerType().equals(AskTypeEnum.COMMAND_N.getCode())){
action.setActionCommand(commands.get(index).getAskKey());
for (Action ac: actions.getActions()
) {
if(!StringUtils.isNotEmpty(ac.getActionCommand())){
ac.setActionCommand(action.getActionCommand());
}
}
}else{
//秋果专有名称
systemTalkAnswerConfigEntities.add(command);
action.setSystemTalkAnswerConfigEntity(command);
action.setAction(command.getAskKey());
action.setName(action.getAction());
actions.setA(1);
actions.setB(1);
}
return action;
}
},

View File

@ -80,9 +80,11 @@ public class AliYunQianWen {
}else{
lastGenerationResult = message;
msgManager.add(lastGenerationResult);
}
} catch (Exception e) {
log.info("千问回调异常{}", e);
qwenReplyResponse.setCode(500);
msgManager = new MessageManager(10);
}
}
@ -90,7 +92,7 @@ public class AliYunQianWen {
@Override
public void onComplete() {
if(lastGenerationResult != null){
msgManager.add(lastGenerationResult);
qwenReplyResponse.setResut(lastGenerationResult.getOutput().getChoices().get(0).getMessage().getContent());
}
@ -102,6 +104,7 @@ public class AliYunQianWen {
public void onError(Exception e) {
log.info("调用千问异常{}", e);
msgManager = new MessageManager(10);
qwenReplyResponse.setCode(500);
semaphore.release();
}
});

View File

@ -40,6 +40,7 @@ public class ActionTime {
//*分钟
//*小时
//*
//*
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
DateTimeFormatter df1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

View File

@ -40,83 +40,71 @@ public class NlpService {
private static Integer MAX_COUT = 2000;
public Mono<Actions> getActionWithLacSingle(Long userId, String text){
if(userId != null){
DeviceUserBindRequest request = new DeviceUserBindRequest();
request.setUserId(userId);
//涂鸦设备
request.setDeviceType(DeviceTypeEnum.ELECTRIC_SOCKET.getCode());
request.setPageSize(MAX_COUT);
return deviceUserBindService.selectDeviceUserBindsByRequest(request).flatMap(deviceUserBindEntityPagerResult -> {
if(deviceUserBindEntityPagerResult.getData().size() > 0){
/*List<DeviceUserBindEntity> list = deviceUserBindEntityPagerResult.getData();
list.sort((a, b) -> {
return b.getBindName().length() - a.getBindName().length();
});//按照名称由长到短排序*/
List<DeviceUserBindEntity> includs = new ArrayList<>();
List<SystemTalkAnswerConfigEntity> commands = new ArrayList<>();
List<SystemTalkKeyAndDeviceName> systemTalkKeyAndDeviceNameList = new ArrayList<>();
int i = 0;
for(SystemTalkAnswerConfigEntity entity : systemTalkAnswerConfigService.getCommandList()){
SystemTalkKeyAndDeviceName systemTalkKeyAndDeviceName = new SystemTalkKeyAndDeviceName();
systemTalkKeyAndDeviceName.setKey(entity.getAskKey());
systemTalkKeyAndDeviceName.setType(KeyTypeEnum.SYSTEM_COMMAND.getCode());
systemTalkKeyAndDeviceName.setIndex(i++);
systemTalkKeyAndDeviceNameList.add(systemTalkKeyAndDeviceName);
}
/*i = 0;
for(SystemTalkAnswerConfigEntity entity : systemTalkAnswerConfigService.getSystemTalkWithKeyGroup().values()){
SystemTalkKeyAndDeviceName systemTalkKeyAndDeviceName = new SystemTalkKeyAndDeviceName();
systemTalkKeyAndDeviceName.setKey(entity.getAskKey());
systemTalkKeyAndDeviceName.setType(KeyTypeEnum.SYSTEM_ACTION.getCode());
systemTalkKeyAndDeviceName.setIndex(i++);
systemTalkKeyAndDeviceNameList.add(systemTalkKeyAndDeviceName);
}*/
i = 0;
for(DeviceUserBindEntity entity : deviceUserBindEntityPagerResult.getData()){
SystemTalkKeyAndDeviceName systemTalkKeyAndDeviceName = new SystemTalkKeyAndDeviceName();
systemTalkKeyAndDeviceName.setKey(entity.getBindName());
systemTalkKeyAndDeviceName.setType(KeyTypeEnum.USER_BIND_NAME.getCode());
systemTalkKeyAndDeviceName.setIndex(i++);
systemTalkKeyAndDeviceNameList.add(systemTalkKeyAndDeviceName);
}
//字符由长到短排序
systemTalkKeyAndDeviceNameList.sort((a, b) ->{
return b.getKey().length() - a.getKey().length();
});
String pText = text;
i = 0;
int j = 0;
for(SystemTalkKeyAndDeviceName sysTalkKeyAndDeviceName :systemTalkKeyAndDeviceNameList){
if(pText.indexOf(sysTalkKeyAndDeviceName.getKey()) >= 0){
//找到对应的名称
if(sysTalkKeyAndDeviceName.getType().equals(KeyTypeEnum.USER_BIND_NAME.getCode())){
//用户绑定设备名称
pText = pText.replace(sysTalkKeyAndDeviceName.getKey(), ">" + (i++) + ">");
includs.add(deviceUserBindEntityPagerResult.getData().get(sysTalkKeyAndDeviceName.getIndex()));
}else if(sysTalkKeyAndDeviceName.getType().equals(KeyTypeEnum.SYSTEM_COMMAND.getCode())){
//是系统自定义动词后的名称
pText = pText.replace(sysTalkKeyAndDeviceName.getKey(), "#" + (j++) + "#");
commands.add(systemTalkAnswerConfigService.getCommandList().get(sysTalkKeyAndDeviceName.getIndex()));
}else{
//系统自定义动作
pText = pText.replace(sysTalkKeyAndDeviceName.getKey(), "<" + (j++) + "<");
commands.add(systemTalkAnswerConfigService.getCommandList().get(sysTalkKeyAndDeviceName.getIndex()));
}
}
}
if(includs.size() > 0) {
return getActions(pText, text, includs, commands);
}
}
return getActions(text, text, null, null);
});
if(userId != null) {
userId = 0L;
}
//20230928日记后期改成先匹配用户的设备名称再找动词
return getActions(text, text, null, null);
DeviceUserBindRequest request = new DeviceUserBindRequest();
request.setUserId(userId);
//涂鸦设备
request.setDeviceType(DeviceTypeEnum.ELECTRIC_SOCKET.getCode());
request.setPageSize(MAX_COUT);
return deviceUserBindService.selectDeviceUserBindsByRequest(request).flatMap(deviceUserBindEntityPagerResult -> {
List<DeviceUserBindEntity> includs = new ArrayList<>();
List<SystemTalkAnswerConfigEntity> systemIncluds = new ArrayList<>();
List<SystemTalkKeyAndDeviceName> systemTalkKeyAndDeviceNameList = new ArrayList<>();
int i = 0;
for(SystemTalkAnswerConfigEntity entity : systemTalkAnswerConfigService.getCommandList()){
SystemTalkKeyAndDeviceName systemTalkKeyAndDeviceName = new SystemTalkKeyAndDeviceName();
systemTalkKeyAndDeviceName.setKey(entity.getAskKey());
if(entity.getAnswerType().equals(KeyTypeEnum.SYSTEM_COMMAND.getCode())) {
systemTalkKeyAndDeviceName.setType(KeyTypeEnum.SYSTEM_COMMAND.getCode());
}else{
systemTalkKeyAndDeviceName.setType(KeyTypeEnum.QIUGUO_NAME.getCode());
}
systemTalkKeyAndDeviceName.setIndex(i++);
systemTalkKeyAndDeviceNameList.add(systemTalkKeyAndDeviceName);
}
i = 0;
for(DeviceUserBindEntity entity : deviceUserBindEntityPagerResult.getData()){
SystemTalkKeyAndDeviceName systemTalkKeyAndDeviceName = new SystemTalkKeyAndDeviceName();
systemTalkKeyAndDeviceName.setKey(entity.getBindName());
systemTalkKeyAndDeviceName.setType(KeyTypeEnum.USER_BIND_NAME.getCode());
systemTalkKeyAndDeviceName.setIndex(i++);
systemTalkKeyAndDeviceNameList.add(systemTalkKeyAndDeviceName);
}
//字符由长到短排序
systemTalkKeyAndDeviceNameList.sort((a, b) ->{
return b.getKey().length() - a.getKey().length();
});
String pText = text;
i = 0;
int j = 0;
for(SystemTalkKeyAndDeviceName sysTalkKeyAndDeviceName :systemTalkKeyAndDeviceNameList){
if(pText.indexOf(sysTalkKeyAndDeviceName.getKey()) >= 0){
//找到对应的名称
if(sysTalkKeyAndDeviceName.getType().equals(KeyTypeEnum.USER_BIND_NAME.getCode())){
//用户绑定设备名称
pText = pText.replace(sysTalkKeyAndDeviceName.getKey(), ">" + (i++) + ">");
includs.add(deviceUserBindEntityPagerResult.getData().get(sysTalkKeyAndDeviceName.getIndex()));
}else{// if(sysTalkKeyAndDeviceName.getType().equals(KeyTypeEnum.SYSTEM_COMMAND.getCode())){
//是系统自定义动词后的名称
pText = pText.replace(sysTalkKeyAndDeviceName.getKey(), "#" + (j++) + "#");
systemIncluds.add(systemTalkAnswerConfigService.getCommandList().get(sysTalkKeyAndDeviceName.getIndex()));
}/*else{
//秋果专有名称
pText = pText.replace(sysTalkKeyAndDeviceName.getKey(), "<" + (j++) + "<");
qiuguoNames.add(systemTalkAnswerConfigService.getQiuGuoOnlyList().get(sysTalkKeyAndDeviceName.getIndex()));
}*/
}
}
return getActions(pText, text, includs, systemIncluds);
});
}
public Mono<Actions> getActions(String text, String recordText,

View File

@ -53,7 +53,7 @@ public class QWenService {
} catch (Exception e) {
log.info("调用千问异常{}", e);
qWenReplyResponse.setCode(500);
//throw new RuntimeException(e);
throw new RuntimeException(e);
}
return qWenReplyResponse;

View File

@ -43,4 +43,9 @@ public class BaseSession {
* 用户登录时同步
*/
protected MusicResp music;
/**
* 调用千问请求序号每次确定调用前++
*/
protected Long requestId = 0L;
}

View File

@ -75,9 +75,11 @@ public class BaseWebSocketProcess {
protected static String apiToken = "api-token";
private void toQianWen(Action action, BaseSession baseSession){
baseSession.setRequestId(baseSession.getRequestId() + 1);
TongYiCommunicationRest tongYiCommunicationRest = new TongYiCommunicationRest();
tongYiCommunicationRest.setText(action.getAsk());
tongYiCommunicationRest.setStatus("2");
tongYiCommunicationRest.setRequestId(baseSession.getRequestId());
if(this instanceof BoxWebSocketHandler){
tongYiCommunicationRest.setOnlyId(baseSession.getSn());
}else{
@ -85,18 +87,28 @@ public class BaseWebSocketProcess {
}
qwenService.communication(tongYiCommunicationRest, message ->{
//通知到客户端
if(tongYiCommunicationRest.getRequestId().equals(baseSession.getRequestId())){
message = message.replace("AI语言模型", "果宝儿Box");
normalSendMsg(baseSession, message, AskTypeEnum.TTS.getCode());
return;
}
log.info("已经有新的请求不在推送到客户端SN{} userId:{}", baseSession.getSn(), baseSession.getUserId());
normalSendMsg(baseSession, message, AskTypeEnum.TTS.getCode());
}).map(data ->{
if(data.getCode() == 200){
log.info("千问正常结束{}", data.getResut());
log.info("千问正常结束");
//保存记录
DeviceUserTalkRecordEntity talkRecord = new DeviceUserTalkRecordEntity();
talkRecord.setAskType(AskTypeEnum.TTS.getCode());
talkRecord.setAskValue(action.getAsk());
talkRecord.setAskKey(action.getAction());
talkRecord.setAnswerValue(data.getResut());
talkRecord.setUserId(baseSession.getUserId());
talkRecord.setDeviceId(baseSession.getDeviceId());
deviceUserTalkRecordService.insertDeviceUserTalkRecord(talkRecord).subscribe();
}else{
sendMessage(action, baseSession, "我还在努力学习中,暂时无法理解", AskTypeEnum.TTS.getCode());
}
return data;
}).subscribeOn(Schedulers.boundedElastic()).subscribe();
}
@ -109,14 +121,18 @@ public class BaseWebSocketProcess {
action.setAsk(actions.getRecordText());
action.setAction(actions.getRecordText());
toQianWen(action, baseSession);
return;
}
boolean isToQianWen = false;
for (Action action : actions.getActions()
) {
log.info("匹配到自定义指令{}", action.getSystemTalkAnswerConfigEntity());
if(action.getSystemTalkAnswerConfigEntity() == null){
log.info("调用千问");
toQianWen(action, baseSession);
if(!isToQianWen){
isToQianWen = true;;
log.info("调用千问,千问只能调用一边");
toQianWen(action, baseSession);
}
//
}else if(action.getSystemTalkAnswerConfigEntity().getAnswerType().equals(AskTypeEnum.IOT.getCode())){
@ -257,6 +273,10 @@ public class BaseWebSocketProcess {
sendMessage(action, baseSession, resp);
}
}else if(action.getSystemTalkAnswerConfigEntity().getAnswerType().equals(AskTypeEnum.TTS.getCode())){
sendMessage(action, baseSession, action.getSystemTalkAnswerConfigEntity().getAnswerValue(), AskTypeEnum.TTS.getCode());
}else if(action.getSystemTalkAnswerConfigEntity().getAnswerType().equals(AskTypeEnum.QIU_GUO.getCode())){
sendMessage(action, baseSession, action.getSystemTalkAnswerConfigEntity().getAnswerValue(), AskTypeEnum.TTS.getCode());
}
}
}
@ -330,7 +350,7 @@ public class BaseWebSocketProcess {
log.info("推送Box播放音乐");
BoxSession boxSession = getBoxSessionWithSn(baseSession.getSn());
if(boxSession != null){
boxSession.getSink().next(baseSession.getSession().textMessage(JSONObject.toJSONString(resp)));
sendMsg(baseSession, JSONObject.toJSONString(resp));
//记录音乐状态
if(resp.getMusic().getPlay().equals(PlayEnum.STOP.getCode())){
//去掉内存中音乐同步对象

View File

@ -138,7 +138,11 @@ public class BoxWebSocketHandler extends BaseWebSocketProcess implements WebSock
}
}
private void errorLogin(BaseSession boxSession, ReactiveValueOperations<String, String> operations, String sn){
//清除异常redis
operations.delete(RedisConstans.DEVICE_INFO + sn).subscribe();//不需要时间
closeSendMsg(boxSession, "异常,请重新登录", AskTypeEnum.TTS.getCode());
}
private void checkToken(BoxSession boxSession, String sn, Long linkTime, String signature, Long userId){
ReactiveValueOperations<String, String> operations = reactiveStringRedisTemplate.opsForValue();
@ -146,12 +150,15 @@ public class BoxWebSocketHandler extends BaseWebSocketProcess implements WebSock
if(com.qiuguo.iot.base.utils.StringUtils.isNotBlank(s)){
try{
DeviceInfoEntity dv = JSONObject.parseObject(s, DeviceInfoEntity.class);
if(dv.getId() == null){
log.info("redis设备缓存异常清楚");
errorLogin(boxSession, operations, sn);
}
return Mono.just(dv);
}catch (Exception e){
log.info("转换异常清除redis。下次连接成功{}", e);
//清除异常redis
operations.set(RedisConstans.DEVICE_INFO + sn, "").subscribe();//不需要时间
closeSendMsg(boxSession, "异常,请重新登录", AskTypeEnum.TTS.getCode());
errorLogin(boxSession, operations, sn);
}
}
DeviceInfoRequest request = new DeviceInfoRequest();