diff --git a/src/main/java/club/joylink/rtss/services/voice/impl/VoiceDataService.java b/src/main/java/club/joylink/rtss/services/voice/impl/VoiceDataService.java index 6d7c6374d..d25b3b807 100644 --- a/src/main/java/club/joylink/rtss/services/voice/impl/VoiceDataService.java +++ b/src/main/java/club/joylink/rtss/services/voice/impl/VoiceDataService.java @@ -10,8 +10,6 @@ import club.joylink.rtss.services.voice.IVoiceDataService; import club.joylink.rtss.simulation.cbtc.command.voice.operate.HandleType; import club.joylink.rtss.simulation.cbtc.command.voice.operate.OperateEnum; import club.joylink.rtss.simulation.cbtc.command.voice.vo.OperateConfigData; -import club.joylink.rtss.simulation.cbtc.command.voice.vo.VoiceConfigData; -import club.joylink.rtss.util.JsonUtils; import club.joylink.rtss.vo.LoginUserInfoVO; import club.joylink.rtss.vo.client.PageVO; import club.joylink.rtss.vo.voice.VoiceConfigVO; @@ -50,8 +48,8 @@ public class VoiceDataService implements IVoiceDataService, IVoiceCommandDataSer private void checkData(VoiceConfigVO dataVO){ BusinessExceptionAssertEnum.DATA_INVALID.assertTrue(Objects.nonNull(dataVO.getWakeUpKw()),String.format("缺少类型匹配")); - BusinessExceptionAssertEnum.DATA_INVALID.assertTrue(ArrayUtils.isNotEmpty(dataVO.getWakeUpKw().getSourceMatch()),String.format("类型匹配需要关键字")); - OperateConfigData configData = dataVO.getConfig().stream().filter(d->ArrayUtils.isEmpty(d.getSourceMatch())).findFirst().orElse(null); + BusinessExceptionAssertEnum.DATA_INVALID.assertTrue(ArrayUtils.isNotEmpty(dataVO.getWakeUpKw().getActionMatch()),String.format("类型匹配需要关键字")); + OperateConfigData configData = dataVO.getConfig().stream().filter(d->ArrayUtils.isEmpty(d.getActionMatch())).findFirst().orElse(null); BusinessExceptionAssertEnum.DATA_INVALID.assertNotTrue(Objects.nonNull(configData),String.format("操作数据关键字不能为空")); Map> mapList = dataVO.getConfig().stream().collect(Collectors.groupingBy(OperateConfigData::getOperate)); for (List value : mapList.values()) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/DeviceVoiceCommandService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/DeviceVoiceCommandService.java index 5ce889200..b8b1603a4 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/DeviceVoiceCommandService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/DeviceVoiceCommandService.java @@ -8,10 +8,13 @@ import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand; import club.joylink.rtss.simulation.cbtc.command.voice.vo.WorkResult; import club.joylink.rtss.simulation.cbtc.command.voice.work.VoiceCommandAnalyseWork; import club.joylink.rtss.simulation.cbtc.data.map.MapNamedElement; +import club.joylink.rtss.simulation.cbtc.data.map.Station; +import club.joylink.rtss.util.PinYinUtil; import club.joylink.rtss.vo.client.voice.VoiceRecognitionResult; import club.joylink.rtss.vo.voice.VoiceConfigVO; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; +import org.ansj.library.DicLibrary; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -38,6 +41,7 @@ public class DeviceVoiceCommandService{ private VoiceCommandAnalyseWork analyseWork; private List findVoiceConfig(Simulation simulation){ + Long mapId = simulation.getBuildParams().getMap().getId(); List configVOList = this.commandDataService.findData(mapId); BusinessExceptionAssertEnum.VOICE_COMMAND_CONFIG_NULL.assertTrue(!CollectionUtils.isEmpty(configVOList),"未找到语音配置的相关信息"); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/VoiceCommandMatchHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/VoiceCommandMatchHandler.java index fff58eeb2..0870822a4 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/VoiceCommandMatchHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/VoiceCommandMatchHandler.java @@ -7,6 +7,7 @@ import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; import java.util.*; @@ -19,8 +20,10 @@ public class VoiceCommandMatchHandler { public List matcher(List configVOList, String msg){ List findParseDataList = Lists.newArrayList(); for (VoiceConfigVO configVO : configVOList) { - Optional> optional = commandMatcher.matchCommand(configVO,msg); - optional.ifPresent(findParseDataList::addAll); + List commandList = commandMatcher.matchCommand(configVO,msg); + if(!CollectionUtils.isEmpty(commandList)){ + findParseDataList.addAll(commandList); + } } return findParseDataList; } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/analyse/PinYinSplitWordAnalyse.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/analyse/PinYinSplitWordAnalyse.java index 74cffe9e0..4d24f0846 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/analyse/PinYinSplitWordAnalyse.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/analyse/PinYinSplitWordAnalyse.java @@ -1,54 +1,86 @@ package club.joylink.rtss.simulation.cbtc.command.voice.analyse; -import club.joylink.rtss.simulation.cbtc.command.voice.operate.HandleType; +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.command.voice.vo.CommandParse; +import club.joylink.rtss.simulation.cbtc.command.voice.vo.ParseDetail; import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand; +import club.joylink.rtss.simulation.cbtc.data.map.Station; import club.joylink.rtss.util.PinYinUtil; +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; import com.google.common.collect.Lists; import org.ansj.domain.Result; import org.ansj.domain.Term; import org.ansj.library.DicLibrary; import org.ansj.splitWord.analysis.DicAnalysis; +import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import java.util.List; import java.util.Objects; public class PinYinSplitWordAnalyse implements VoiceCommandAnalyse { - @Override - public synchronized List parseCommandDescribe(DeviceVoiceCommand command) { - this.initDic(command); - String pinyinStr = PinYinUtil.toPinYinSplitBlankSpace(command.getSourceDescrbe()); + @Override + public synchronized CommandParse parseCommandDescribe(Simulation simulation, DeviceVoiceCommand command) { + this.initDic(simulation,command); + String pinyinStr = PinYinUtil.toPinYinSplitBlankSpace(command.getSourceDescrbe()); Result reslut = DicAnalysis.parse(pinyinStr); - List resultList = Lists.newArrayList(); + List resultList = Lists.newArrayList(); + CommandParse commandParse = new CommandParse(command.getSourceDescrbe(),pinyinStr); + commandParse.setDetail(resultList); for (Term term : reslut) { String name = term.getName().toUpperCase(); String nature = term.getNatureStr(); - if(Objects.nonNull(nature) && !StringUtils.startsWith(nature,"w")){ - if(!StringUtils.equalsIgnoreCase(nature,"userDefine")){ -// command.appendCommandDescribe(name); - resultList.add(name); - }/*else{ - command.appendCommandDescribe(name); - }*/ + if(Objects.nonNull(nature) && StringUtils.isNotEmpty(name) && !StringUtils.startsWith(nature,"w")){ + if(!StringUtils.equalsIgnoreCase(nature,DicLibrary.DEFAULT_NATURE)){ + resultList.add(new ParseDetail(name,nature,term.getOffe(), term.toValue())); + } } -// commandList.add(command); } - return resultList; + return commandParse; } -/* @Override - public HandleType handleType() { - return HandleType.PINYIN; - }*/ - private void initDic(DeviceVoiceCommand command){ + + private void initDic(Simulation simulation,DeviceVoiceCommand command){ DicLibrary.clear(DicLibrary.DEFAULT); + for (Station station : simulation.getRepository().getStationList()) { + String pinYinTmp = PinYinUtil.toPinYinSplitBlankSpace(station.getName()).toLowerCase(); + List pinyin = Splitter.onPattern("\\s").omitEmptyStrings().splitToList(pinYinTmp); + + DicLibrary.insert(DicLibrary.DEFAULT,pinYinTmp,VoiceCommandAnalyse.DESCRIBE_NATURE,DicLibrary.DEFAULT_FREQ); + List> subPinYinList = Lists.partition(pinyin,2); + for (List strings : subPinYinList) { + String t = Joiner.on(" ").skipNulls().join(strings); + DicLibrary.insert(DicLibrary.DEFAULT,t,VoiceCommandAnalyse.DESCRIBE_NATURE,DicLibrary.DEFAULT_FREQ); + } + subPinYinList = Lists.partition(pinyin,3); + for (List strings : subPinYinList) { + String t = Joiner.on(" ").skipNulls().join(strings); + DicLibrary.insert(DicLibrary.DEFAULT,t,VoiceCommandAnalyse.DESCRIBE_NATURE,DicLibrary.DEFAULT_FREQ); + } + } + + for (String s : command.getTranslateWakeUpKW()) { - DicLibrary.insert(DicLibrary.DEFAULT,s,DicLibrary.DEFAULT_NATURE,DicLibrary.DEFAULT_FREQ); + DicLibrary.insert(DicLibrary.DEFAULT,s.toLowerCase(),DicLibrary.DEFAULT_NATURE,DicLibrary.DEFAULT_FREQ); } - for (String s : command.getMatchCommandKW()) { - DicLibrary.insert(DicLibrary.DEFAULT,s,DicLibrary.DEFAULT_NATURE,DicLibrary.DEFAULT_FREQ); + + for (String s : command.getOperateConfigData().getTranslateActionMatch()) { + DicLibrary.insert(DicLibrary.DEFAULT,s.toLowerCase(),DicLibrary.DEFAULT_NATURE,DicLibrary.DEFAULT_FREQ); } + + if(ArrayUtils.isNotEmpty(command.getOperateConfigData().getTranslateNatureKW())){ + for (String s : command.getOperateConfigData().getTranslateNatureKW()) { + DicLibrary.insert(DicLibrary.DEFAULT,s.toLowerCase(),VoiceCommandAnalyse.DESCRIBE_NATURE,DicLibrary.DEFAULT_FREQ); + } + } + +/* if(ArrayUtils.isNotEmpty(command.getOperateConfigData().getTranslateDescribeKW())){ + for (String s : command.getOperateConfigData().getTranslateDescribeKW()) { + DicLibrary.insert(DicLibrary.DEFAULT,s.toLowerCase(),DicLibrary.DEFAULT_NATURE,DicLibrary.DEFAULT_FREQ); + } + }*/ } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/analyse/VoiceCommandAnalyse.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/analyse/VoiceCommandAnalyse.java index d7527a441..a9f9cb084 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/analyse/VoiceCommandAnalyse.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/analyse/VoiceCommandAnalyse.java @@ -1,16 +1,16 @@ package club.joylink.rtss.simulation.cbtc.command.voice.analyse; +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.command.voice.vo.CommandParse; import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand; -import java.util.List; - public interface VoiceCommandAnalyse { - + String DESCRIBE_NATURE = "nature"; /** * 解析命令 * @param Command 命令原文 * @return 解析后的数据 */ - List parseCommandDescribe(DeviceVoiceCommand Command); + CommandParse parseCommandDescribe(Simulation simulation, DeviceVoiceCommand Command); } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/match/IMatchFilter.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/match/IMatchFilter.java new file mode 100644 index 000000000..b642cc5f4 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/match/IMatchFilter.java @@ -0,0 +1,14 @@ +package club.joylink.rtss.simulation.cbtc.command.voice.match; + +import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand; +import club.joylink.rtss.vo.voice.VoiceConfigVO; + +import java.util.List; +import java.util.Optional; + +public interface IMatchFilter { + List filter(); + + Optional> matchCommand(VoiceConfigVO configVOList, String msg); + +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/match/IVoiceCommandMatcher.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/match/IVoiceCommandMatcher.java index 73b134b37..a40ccc074 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/match/IVoiceCommandMatcher.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/match/IVoiceCommandMatcher.java @@ -1,15 +1,13 @@ package club.joylink.rtss.simulation.cbtc.command.voice.match; -import club.joylink.rtss.simulation.cbtc.command.voice.operate.HandleType; import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand; import club.joylink.rtss.vo.voice.VoiceConfigVO; import java.util.List; -import java.util.Optional; public interface IVoiceCommandMatcher { - Optional> matchCommand(VoiceConfigVO configVOList, String msg); + List matchCommand(VoiceConfigVO configVOList, String msg); // HandleType handleType(); } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/match/PinYinViolenceMatchHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/match/PinYinViolenceMatchHandler.java index 845c01fcf..5a9985776 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/match/PinYinViolenceMatchHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/match/PinYinViolenceMatchHandler.java @@ -4,43 +4,48 @@ import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand; import club.joylink.rtss.simulation.cbtc.command.voice.vo.OperateConfigData; import club.joylink.rtss.util.PinYinUtil; import club.joylink.rtss.vo.voice.VoiceConfigVO; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; -import org.springframework.util.CollectionUtils; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.Optional; import java.util.stream.Collectors; - +@Slf4j public class PinYinViolenceMatchHandler implements IVoiceCommandMatcher { @Override - public Optional> matchCommand(VoiceConfigVO configVO, String sourceMsg) { + public List matchCommand(VoiceConfigVO configVO, String sourceMsg) { String tmpPinYinContent = PinYinUtil.toPinYinSplitBlankSpace(sourceMsg); List commandList = this.match(configVO,sourceMsg,tmpPinYinContent); commandList = commandList.stream().filter(d->Objects.nonNull(d.getDeviceType()) - && ArrayUtils.isNotEmpty(d.getMatchCommandKW()) + && Objects.nonNull(d.getOperateConfigData()) && ArrayUtils.isNotEmpty(d.getTranslateWakeUpKW()) ).collect(Collectors.toList()); - if(CollectionUtils.isEmpty(commandList)){ - return Optional.empty(); - } - return Optional.of(commandList); + return commandList; } private List match(VoiceConfigVO configVO,String sourceMsg, String pinyinStr){ List commandList = new ArrayList<>(); for (OperateConfigData configData : configVO.getConfig()) { DeviceVoiceCommand command = new DeviceVoiceCommand(configVO.getHandleType()); - if(StringUtils.containsAny(pinyinStr,configVO.getWakeUpKw().getTranslateMatch())){ + if(StringUtils.containsAny(pinyinStr,configVO.getWakeUpKw().getTranslateActionMatch())){ command.setDeviceType(configVO.getDeviceType()); - command.setTranslateWakeUpKW(configVO.getWakeUpKw().getTranslateMatch()); + command.setTranslateWakeUpKW(configVO.getWakeUpKw().getTranslateActionMatch()); } - if(StringUtils.containsAny(pinyinStr,configData.getTranslateMatch())){ - command.setOperateConfigData(configData); - command.setMatchCommandKW(configData.getTranslateMatch()); + if(StringUtils.containsAny(pinyinStr,configData.getTranslateActionMatch())){ + if(configData.isForceMatchNature()){ + if(ArrayUtils.isEmpty(configData.getTranslateNatureKW())){ + log.error("强制匹配属性,但是属性为空 config id[{}]",configVO.getId()); + return Collections.emptyList(); + }else if(StringUtils.containsAny(pinyinStr,configData.getTranslateNatureKW())){ + command.setOperateConfigData(configData); + } + }else{ + command.setOperateConfigData(configData); + } } command.setSourceDescrbe(sourceMsg); commandList.add(command); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/operate/OperateDeviceEnum.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/operate/OperateDeviceEnum.java deleted file mode 100644 index d279e898f..000000000 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/operate/OperateDeviceEnum.java +++ /dev/null @@ -1,12 +0,0 @@ -package club.joylink.rtss.simulation.cbtc.command.voice.operate; - -import java.util.List; - -public enum OperateDeviceEnum { - SWITCH(); - private OperateEnum[] operates; - - OperateDeviceEnum(OperateEnum... operates) { - this.operates = operates; - } -} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/operate/OperateEnum.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/operate/OperateEnum.java index 36097b96e..bf9eccb24 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/operate/OperateEnum.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/operate/OperateEnum.java @@ -1,5 +1,6 @@ package club.joylink.rtss.simulation.cbtc.command.voice.operate; +import club.joylink.rtss.simulation.cbtc.ATS.service.AtsStandService; import club.joylink.rtss.simulation.cbtc.CI.device.CiSwitchControlService; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.data.map.MapElement; @@ -11,24 +12,69 @@ import lombok.Getter; public enum OperateEnum { SWITCH_DINGWEI(MapElement.DeviceType.SWITCH,"定位"){ @Override - public void handle(Simulation simulation,CiSwitchControlService service, MapElement device) { + public void handle(Simulation simulation,Object objectService, MapElement device) { Switch aswitch = (Switch)device; - service.turn2NormalPosition(simulation,aswitch); + CiSwitchControlService controlService = (CiSwitchControlService) objectService; + controlService.turn2NormalPosition(simulation,aswitch); } }, SWITCH_FANWEI(MapElement.DeviceType.SWITCH,"反位"){ @Override - public void handle(Simulation simulation, CiSwitchControlService service, MapElement device) { + public void handle(Simulation simulation, Object objectService, MapElement device) { Switch aswitch = (Switch)device; - service.turn2ReversePosition(simulation,aswitch); + CiSwitchControlService controlService = (CiSwitchControlService) objectService; + controlService.turn2ReversePosition(simulation,aswitch); } - } + }, + STAND_HOLD_TRAIN(MapElement.DeviceType.STAND,"扣车"){ + @Override + public void handle(Simulation simulation, Object objectService, MapElement device) { + AtsStandService standService = (AtsStandService) objectService; + standService.holdTrain(simulation,device.getCode()); + } + }, + STAND_CANCEL_HOLD_TRAIN(MapElement.DeviceType.STAND,"取消扣车"){ + @Override + public void handle(Simulation simulation, Object objectService, MapElement device) { + AtsStandService standService = (AtsStandService) objectService; + standService.cancelHoldTrain(simulation,device.getCode()); + } + }, + STAND_UP_HOLD_TRAIN(MapElement.DeviceType.STAND,"上行扣车"){ + @Override + public void handle(Simulation simulation, Object objectService, MapElement device) { + AtsStandService standService = (AtsStandService) objectService; + standService.holdTrain(simulation,device.getCode()); + } + }, + STAND_DOWN_HOLD_TRAIN(MapElement.DeviceType.STAND,"下行扣车"){ + @Override + public void handle(Simulation simulation, Object objectService, MapElement device) { + AtsStandService standService = (AtsStandService) objectService; + standService.holdTrain(simulation,device.getCode()); + } + }, + STAND_CANCEL_UP_HOLD_TRAIN(MapElement.DeviceType.STAND,"上行取消扣车"){ + @Override + public void handle(Simulation simulation, Object objectService, MapElement device) { + AtsStandService standService = (AtsStandService) objectService; + standService.cancelHoldTrain(simulation,device.getCode()); + } + }, + STAND_CANCEL_DOWN_HOLD_TRAIN(MapElement.DeviceType.STAND,"下行取消扣车"){ + @Override + public void handle(Simulation simulation, Object objectService, MapElement device) { + AtsStandService standService = (AtsStandService) objectService; + standService.cancelHoldTrain(simulation,device.getCode()); + } + }, + ; private MapElement.DeviceType deviceType; @Getter private String describe; - public abstract void handle(Simulation simulation,CiSwitchControlService service, MapElement device); + public abstract void handle(Simulation simulation,Object objectService, MapElement device); OperateEnum(MapElement.DeviceType deviceType, String describe) { this.deviceType = deviceType; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/CommandParse.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/CommandParse.java new file mode 100644 index 000000000..5f5879915 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/CommandParse.java @@ -0,0 +1,31 @@ +package club.joylink.rtss.simulation.cbtc.command.voice.vo; + +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.stream.Collectors; + +@Data +@NoArgsConstructor +public class CommandParse { + private String descrbeCommand; + private String translateDescrbeCommand; + + private List detail; + + public CommandParse(String descrbeCommand, String translateDescrbeCommand) { + this.descrbeCommand = descrbeCommand; + this.translateDescrbeCommand = translateDescrbeCommand; + } + + public List findNatureDetail(String nature){ + return this.detail.stream().filter(d-> StringUtils.equalsIgnoreCase(d.getNature(), nature)).collect(Collectors.toList()); + } + + public List findNotNatureDetail(String nature){ + return this.detail.stream().filter(d->!StringUtils.equalsIgnoreCase(d.getNature(),nature)).collect(Collectors.toList()); + + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/DeviceVoiceCommand.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/DeviceVoiceCommand.java index c665d0754..990789469 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/DeviceVoiceCommand.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/DeviceVoiceCommand.java @@ -26,17 +26,10 @@ public class DeviceVoiceCommand { /** * 匹配的命令关键字 */ - private String[] matchCommandKW; - private String matchCommandDescribe; +// private String[] matchCommandKW; +// private String matchCommandDescribe; - public void appendCommandDescribe(String d){ - if(Objects.isNull(this.matchCommandDescribe)){ - this.matchCommandDescribe = d; - }else{ - this.matchCommandDescribe = this.matchCommandDescribe.concat(d); - } - } @Override public String toString(){ diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/OperateConfigData.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/OperateConfigData.java index 478c0efe6..920db10ea 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/OperateConfigData.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/OperateConfigData.java @@ -9,6 +9,22 @@ import lombok.NoArgsConstructor; public class OperateConfigData extends VoiceConfigData { private OperateEnum operate; + /** + * 描述 + */ +// private String[] describeKW; +// private String[] translateDescribeKW; + /** + * 属性关键字 + */ + private String[] natureKW; + private String[] translateNatureKW; + + /** + * 是否强制匹配属性关键字 + */ + private boolean forceMatchNature; + public OperateConfigData(OperateEnum operate) { this.operate = operate; } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/ParseDetail.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/ParseDetail.java new file mode 100644 index 000000000..ed6c2877b --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/ParseDetail.java @@ -0,0 +1,20 @@ +package club.joylink.rtss.simulation.cbtc.command.voice.vo; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class ParseDetail { + private String name; + private String nature; + private int index; + private int end; + + public ParseDetail(String name, String meta, int index, int end) { + this.name = name; + this.nature = meta; + this.index = index; + this.end = end; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/VoiceConfigData.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/VoiceConfigData.java index 3f326ae90..2a4ba0234 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/VoiceConfigData.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/vo/VoiceConfigData.java @@ -4,7 +4,10 @@ import lombok.Data; @Data public class VoiceConfigData { - private String[] sourceMatch; - private String[] translateMatch; + /** + * 激活匹配关键字 + */ + private String[] actionMatch; + private String[] translateActionMatch; } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/work/IDeviceWork.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/work/IDeviceWork.java index a90a4a804..58b6e833d 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/work/IDeviceWork.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/work/IDeviceWork.java @@ -1,7 +1,9 @@ package club.joylink.rtss.simulation.cbtc.command.voice.work; import club.joylink.rtss.simulation.cbtc.Simulation; -import club.joylink.rtss.simulation.cbtc.command.voice.vo.WorkResult; +import club.joylink.rtss.simulation.cbtc.command.voice.vo.CommandParse; +import club.joylink.rtss.simulation.cbtc.command.voice.vo.ParseDetail; +import club.joylink.rtss.simulation.cbtc.command.voice.vo.OperateConfigData; import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand; import club.joylink.rtss.simulation.cbtc.data.map.MapElement; import club.joylink.rtss.simulation.cbtc.data.map.MapNamedElement; @@ -11,8 +13,22 @@ import java.util.Optional; public interface IDeviceWork { - Optional findDevice(Simulation simulation, List matchCommandDescribe); - WorkResult work(Simulation simulation, DeviceVoiceCommand command, MapElement device); + /** + * 根据分析出的数据查找对应的设备 + * @param simulation + * @param matchCommandDescribe + * @return + */ + Optional findDevice(Simulation simulation, CommandParse commandParse, OperateConfigData configData); + + /** + * 执行对应的操作 + * @param simulation + * @param command + * @param device + * @return + */ + void work(Simulation simulation, DeviceVoiceCommand command, MapElement device); MapElement.DeviceType deviceType(); } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/work/VoiceCommandAnalyseWork.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/work/VoiceCommandAnalyseWork.java index 6c3e3a04a..601c263c9 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/work/VoiceCommandAnalyseWork.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/work/VoiceCommandAnalyseWork.java @@ -3,6 +3,8 @@ package club.joylink.rtss.simulation.cbtc.command.voice.work; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.command.voice.analyse.VoiceCommandAnalyse; +import club.joylink.rtss.simulation.cbtc.command.voice.vo.CommandParse; +import club.joylink.rtss.simulation.cbtc.command.voice.vo.ParseDetail; import club.joylink.rtss.simulation.cbtc.command.voice.vo.WorkResult; import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand; import club.joylink.rtss.simulation.cbtc.data.map.MapElement; @@ -31,12 +33,18 @@ public class VoiceCommandAnalyseWork { return deviceWork; } + /** + * 分析语音指令的描述,并返回查找对应的设备 + * @param simulation + * @param command + * @return + */ public Optional analyse(Simulation simulation, DeviceVoiceCommand command) { IDeviceWork deviceWork = this.findDeviceWork(command.getDeviceType()); - List findDeviceNames = this.commandAnalyse.parseCommandDescribe(command); - command.setMatchCommandDescribe(Joiner.on(",").join(findDeviceNames)); - Optional optional = deviceWork.findDevice(simulation,findDeviceNames); - return optional; + CommandParse commandParse = this.commandAnalyse.parseCommandDescribe(simulation,command); +// command.setMatchCommandDescribe(Joiner.on(",").join(findDeviceNames)); + Optional optional = deviceWork.findDevice(simulation,commandParse,command.getOperateConfigData()); + return (Optional) optional; } public WorkResult work(Simulation simulation, DeviceVoiceCommand command, MapNamedElement device){ diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/work/device/StandWork.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/work/device/StandWork.java new file mode 100644 index 000000000..47f9e8be5 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/work/device/StandWork.java @@ -0,0 +1,71 @@ +package club.joylink.rtss.simulation.cbtc.command.voice.work.device; + +import club.joylink.rtss.simulation.cbtc.ATS.service.AtsStandService; +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.command.voice.analyse.VoiceCommandAnalyse; +import club.joylink.rtss.simulation.cbtc.command.voice.operate.OperateEnum; +import club.joylink.rtss.simulation.cbtc.command.voice.vo.CommandParse; +import club.joylink.rtss.simulation.cbtc.command.voice.vo.ParseDetail; +import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand; +import club.joylink.rtss.simulation.cbtc.command.voice.vo.OperateConfigData; +import club.joylink.rtss.simulation.cbtc.command.voice.work.IDeviceWork; +import club.joylink.rtss.simulation.cbtc.data.map.*; +import club.joylink.rtss.util.PinYinUtil; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.text.similarity.JaroWinklerSimilarity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +@Component +public class StandWork implements IDeviceWork { + @Autowired + private AtsStandService atsStandService; + + + private String findStationCode(Simulation simulation, CommandParse commandParse){ + List findCommandParse = commandParse.findNotNatureDetail(VoiceCommandAnalyse.DESCRIBE_NATURE); + JaroWinklerSimilarity similarity = new JaroWinklerSimilarity(); + Map similarityMaper = new HashMap<>(); + for (Station station : simulation.getRepository().getStationList()) { + String stationName = station.getName(); + String pinYinStation = PinYinUtil.toPinYinSplitBlankSpace(stationName); + for (ParseDetail cp : findCommandParse) { + double scope = similarity.apply(pinYinStation,cp.getName()); + similarityMaper.put(scope,station.getCode()); + } + } + if(similarityMaper.isEmpty()){ + return null; + } + double max = similarityMaper.keySet().stream().mapToDouble(d->d).max().getAsDouble(); + return similarityMaper.get(max); + } + + @Override + public Optional findDevice(Simulation simulation, CommandParse commandParse, OperateConfigData configData) { + String stationCode = this.findStationCode(simulation,commandParse); + if(StringUtils.isEmpty(stationCode)){ + return Optional.empty(); + } + OperateEnum configOperateEnum = configData.getOperate(); + final boolean isRight = (configOperateEnum == OperateEnum.STAND_DOWN_HOLD_TRAIN || configOperateEnum == OperateEnum.STAND_CANCEL_DOWN_HOLD_TRAIN) ? false : true; + Optional stand = simulation.getRepository().getStandList().stream().filter(d->d.isRight() == isRight && StringUtils.equalsIgnoreCase(d.getStation().getCode(),stationCode)).findFirst(); + return stand; + } + + @Override + public void work(Simulation simulation, DeviceVoiceCommand command, MapElement device) { + command.getOperateConfigData().getOperate().handle(simulation,this.atsStandService,device); + } + + @Override + public MapElement.DeviceType deviceType() { + return MapElement.DeviceType.STAND; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/work/device/SwitchWork.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/work/device/SwitchWork.java index 82684efe3..3958c712f 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/work/device/SwitchWork.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/voice/work/device/SwitchWork.java @@ -2,7 +2,9 @@ package club.joylink.rtss.simulation.cbtc.command.voice.work.device; import club.joylink.rtss.simulation.cbtc.CI.device.CiSwitchControlService; import club.joylink.rtss.simulation.cbtc.Simulation; -import club.joylink.rtss.simulation.cbtc.command.voice.vo.WorkResult; +import club.joylink.rtss.simulation.cbtc.command.voice.vo.CommandParse; +import club.joylink.rtss.simulation.cbtc.command.voice.vo.ParseDetail; +import club.joylink.rtss.simulation.cbtc.command.voice.vo.OperateConfigData; import club.joylink.rtss.simulation.cbtc.command.voice.vo.DeviceVoiceCommand; import club.joylink.rtss.simulation.cbtc.command.voice.work.IDeviceWork; import club.joylink.rtss.simulation.cbtc.data.map.MapElement; @@ -24,13 +26,13 @@ public class SwitchWork implements IDeviceWork { private CiSwitchControlService ciSwitchControlService; @Override - public Optional findDevice(Simulation simulation, List matchCommandDescribe) { + public Optional findDevice(Simulation simulation, CommandParse commandParse, OperateConfigData configData) { JaroWinklerSimilarity similarity = new JaroWinklerSimilarity(); Map similarityMaper = new HashMap<>(); for (Switch aSwitch : simulation.getRepository().getSwitchList()) { String switchName = aSwitch.getName(); - for (String findDeviceName : matchCommandDescribe) { - double scope = similarity.apply(switchName.toUpperCase(),findDeviceName); + for (ParseDetail cp : commandParse.getDetail()) { + double scope = similarity.apply(switchName.toUpperCase(),cp.getName()); similarityMaper.put(scope,aSwitch.getCode()); } } @@ -45,9 +47,9 @@ public class SwitchWork implements IDeviceWork { } @Override - public WorkResult work(Simulation simulation, DeviceVoiceCommand command, MapElement device) { + public void work(Simulation simulation, DeviceVoiceCommand command, MapElement device) { command.getOperateConfigData().getOperate().handle(simulation,this.ciSwitchControlService,device); - return null; + } @Override diff --git a/src/main/java/club/joylink/rtss/util/PinYinUtil.java b/src/main/java/club/joylink/rtss/util/PinYinUtil.java index f406f8e4d..dc2f8aa44 100644 --- a/src/main/java/club/joylink/rtss/util/PinYinUtil.java +++ b/src/main/java/club/joylink/rtss/util/PinYinUtil.java @@ -1,11 +1,14 @@ package club.joylink.rtss.util; +import com.google.common.base.Splitter; import net.sourceforge.pinyin4j.PinyinHelper; import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType; import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat; import net.sourceforge.pinyin4j.format.HanyuPinyinToneType; import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination; +import java.util.List; + public class PinYinUtil { private final static HanyuPinyinOutputFormat PIN_YIN_FORMAT = new HanyuPinyinOutputFormat(); @@ -37,6 +40,11 @@ public class PinYinUtil { } return result; } + + public static List toPinyinList(String sourceMsg){ + String tmpPinyinStr = toPinYinSplitBlankSpace(sourceMsg); + return Splitter.onPattern("\\s").omitEmptyStrings().splitToList(tmpPinyinStr); + } public static String toPinYinSplitBlankSpace(String sourceMsg){ StringBuilder sb = new StringBuilder(); for(char c : sourceMsg.toCharArray()){ diff --git a/src/main/java/club/joylink/rtss/vo/voice/VoiceConfigVO.java b/src/main/java/club/joylink/rtss/vo/voice/VoiceConfigVO.java index 7d41d2516..fd2ef2d45 100644 --- a/src/main/java/club/joylink/rtss/vo/voice/VoiceConfigVO.java +++ b/src/main/java/club/joylink/rtss/vo/voice/VoiceConfigVO.java @@ -16,7 +16,6 @@ import org.springframework.util.StringUtils; import java.io.Serializable; import java.time.LocalDateTime; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -73,14 +72,20 @@ public class VoiceConfigVO implements Serializable { VoiceDeviceConfig vc = new VoiceDeviceConfig(); if(Objects.nonNull(this.wakeUpKw)){ if(this.handleType == HandleType.PINYIN){ - this.wakeUpKw.setTranslateMatch(PinYinUtil.toPinYins(this.wakeUpKw.getSourceMatch())); + this.wakeUpKw.setTranslateActionMatch(PinYinUtil.toPinYins(this.wakeUpKw.getActionMatch())); } vc.setWakeUpKw(JsonUtils.writeValueAsString(this.wakeUpKw)); } if(!CollectionUtils.isEmpty(this.config)){ for (OperateConfigData configData : this.config) { if(this.handleType == HandleType.PINYIN){ - configData.setTranslateMatch(PinYinUtil.toPinYins(configData.getSourceMatch())); + configData.setTranslateActionMatch(PinYinUtil.toPinYins(configData.getActionMatch())); + if(ArrayUtils.isNotEmpty(configData.getDescribeKW())){ + configData.setTranslateDescribeKW(PinYinUtil.toPinYins(configData.getDescribeKW())); + } + if(ArrayUtils.isNotEmpty(configData.getNatureKW())){ + configData.setTranslateNatureKW(PinYinUtil.toPinYins(configData.getNatureKW())); + } } } vc.setConfig(JsonUtils.writeValueAsString(this.config)); diff --git a/src/test/java/club/joylink/rtss/services/util/SplitWordTest.java b/src/test/java/club/joylink/rtss/services/util/SplitWordTest.java index 92688af1f..e74b1db72 100644 --- a/src/test/java/club/joylink/rtss/services/util/SplitWordTest.java +++ b/src/test/java/club/joylink/rtss/services/util/SplitWordTest.java @@ -1,27 +1,37 @@ package club.joylink.rtss.services.util; +import club.joylink.rtss.util.PinYinUtil; import org.ansj.domain.Result; import org.ansj.domain.Term; import org.ansj.library.DicLibrary; import org.ansj.splitWord.analysis.DicAnalysis; +import org.nlpcn.commons.lang.tire.domain.Forest; public class SplitWordTest { public static void main(String[] args) throws Exception { - DicLibrary.insert(DicLibrary.DEFAULT, "dao cha", DicLibrary.DEFAULT_NATURE, 1); - DicLibrary.insert(DicLibrary.DEFAULT, "ding wei", DicLibrary.DEFAULT_NATURE, 1); - DicLibrary.insert(DicLibrary.DEFAULT, "fan wei", DicLibrary.DEFAULT_NATURE, 1); - DicLibrary.insert(DicLibrary.DEFAULT, "ban li", DicLibrary.DEFAULT_NATURE, 1); - -// print("1234asdfa"); -// print("BAN LI|p0707|daochadingwei|"); - print("BAN LI p0707 dao cha ding wei"); +// DicLibrary.insert(DicLibrary.DEFAULT, "dao cha", DicLibrary.DEFAULT_NATURE, 1); +// DicLibrary.insert(DicLibrary.DEFAULT, "ding wei", DicLibrary.DEFAULT_NATURE, 1); +// DicLibrary.insert(DicLibrary.DEFAULT, "fan wei", DicLibrary.DEFAULT_NATURE, 1); +// DicLibrary.insert(DicLibrary.DEFAULT, "ban li", DicLibrary.DEFAULT_NATURE, 1); +// DicLibrary.put("user",null); +// DicLibrary.put("user", "user", new Forest()); +// DicLibrary.insert("user", PinYinUtil.toPinYinSplitBlankSpace("车险").toLowerCase(),"user",1000); + DicLibrary.insert(DicLibrary.DEFAULT, "zhan tai", DicLibrary.DEFAULT_NATURE, 1); + DicLibrary.insert(DicLibrary.DEFAULT, "zhan", "xxxws", 1); + DicLibrary.insert(DicLibrary.DEFAULT, "zhan", "user", 1); + DicLibrary.insert(DicLibrary.DEFAULT, "shang xing", DicLibrary.DEFAULT_NATURE, 1); + DicLibrary.insert(DicLibrary.DEFAULT, "kou che", DicLibrary.DEFAULT_NATURE, 1); + String source = "车险 车站01上行站台扣车"; + String pinyin = PinYinUtil.toPinYinSplitBlankSpace(source); + print(pinyin); } private static void print(String s) throws Exception { // print(BaseAnalysis.parse(s)); // print(ToAnalysis.parse(s)); + // print(IndexAnalysis.parse(s)); - print(DicAnalysis.parse(s)); + print(DicAnalysis.parse(s,DicLibrary.get("user"))); // print(NlpAnalysis.parse(s)); // print(DicAnalysis.parse(s)); } diff --git a/src/test/java/club/joylink/rtss/services/voice/SimulationVoiceTest.java b/src/test/java/club/joylink/rtss/services/voice/SimulationVoiceTest.java index 87024e563..c93dde717 100644 --- a/src/test/java/club/joylink/rtss/services/voice/SimulationVoiceTest.java +++ b/src/test/java/club/joylink/rtss/services/voice/SimulationVoiceTest.java @@ -95,4 +95,15 @@ public class SimulationVoiceTest { System.out.println(result); } } + @Test + public void newTestStand(){ + LoginUserInfoVO userInfoVO = this.getInfo(); + String simKey = simulationService.createSimulation(10642L,userInfoVO); + Simulation simulation = (Simulation)this.simulationManager.getById(simKey); + List results = this.commandService.voiceCommand(simulation,"办理车站十上行站台扣车"); +// List results = this.commandService.voiceCommand(simulation,"办理车站1上行站台扣车"); + for (WorkResult result : results) { + System.out.println(result); + } + } } diff --git a/src/test/java/club/joylink/rtss/services/voice/VoiceDataManageTest.java b/src/test/java/club/joylink/rtss/services/voice/VoiceDataManageTest.java index 09bf677e7..e0b8c77d7 100644 --- a/src/test/java/club/joylink/rtss/services/voice/VoiceDataManageTest.java +++ b/src/test/java/club/joylink/rtss/services/voice/VoiceDataManageTest.java @@ -50,19 +50,45 @@ public class VoiceDataManageTest { configVO.setDeviceType(MapElement.DeviceType.SWITCH); configVO.setMapId(50L); VoiceConfigData config = new VoiceConfigData(); - config.setSourceMatch(new String[]{"道岔"}); + config.setActionMatch(new String[]{"道岔"}); configVO.setWakeUpKw(config); List configDataList = Lists.newArrayList(); OperateConfigData configData = new OperateConfigData(OperateEnum.SWITCH_DINGWEI); - configData.setSourceMatch(new String[]{"定位"}); + configData.setActionMatch(new String[]{"定位"}); configDataList.add(configData); configData = new OperateConfigData(OperateEnum.SWITCH_FANWEI); - configData.setSourceMatch(new String[]{"反位"}); + configData.setActionMatch(new String[]{"反位"}); + configDataList.add(configData); + configVO.setConfig(configDataList); + this.dataService.saveOrUpdate(configVO,userInfoVO); + } + @Test +// @Rollback + public void insertDataStand(){ + LoginUserInfoVO userInfoVO = this.getInfo(); + VoiceConfigVO configVO = new VoiceConfigVO(); + configVO.setId(11L); + configVO.setHandleType(HandleType.PINYIN); + configVO.setDescribe("测试站台"); + configVO.setDeviceType(MapElement.DeviceType.STAND); + configVO.setMapId(63L); + VoiceConfigData config = new VoiceConfigData(); + config.setActionMatch(new String[]{"站台"}); + configVO.setWakeUpKw(config); + List configDataList = Lists.newArrayList(); + OperateConfigData configData = new OperateConfigData(OperateEnum.STAND_UP_HOLD_TRAIN); + configData.setActionMatch(new String[]{"扣车"}); + configData.setNatureKW(new String[]{"上行","上"}); +// configData.setDescribeKW(new String[]{"站"}); + configDataList.add(configData); + configData = new OperateConfigData(OperateEnum.STAND_CANCEL_UP_HOLD_TRAIN); + configData.setActionMatch(new String[]{"取消扣车","取消"}); + configData.setNatureKW(new String[]{"上行","上"}); +// configData.setDescribeKW(new String[]{"站"}); configDataList.add(configData); configVO.setConfig(configDataList); this.dataService.saveOrUpdate(configVO,userInfoVO); } - @Test public void findData(){ VoiceConfigVO vo1 = this.dataService.byId(7L);