package com.jcdm.main.plcserver.sub; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.jcdm.main.bs.domain.BsTechnologyRouteChildInfo; import com.jcdm.main.bs.orderScheduling.domain.BsOrderScheduling; import com.jcdm.main.bs.orderScheduling.service.IBsOrderSchedulingService; import com.jcdm.main.bs.technologyRouteChild.service.IBsTechnologyRouteChildInfoService; import com.jcdm.main.da.collectionParamConf.domain.DaCollectionParamConf; import com.jcdm.main.da.collectionParamConf.service.IDaCollectionParamConfService; import com.jcdm.main.da.opcuaconfig.domain.DaOpcuaConfig; import com.jcdm.main.da.paramCollection.domain.DaParamCollection; import com.jcdm.main.da.paramCollection.service.IDaParamCollectionService; import com.jcdm.main.da.passingStationCollection.domain.DaPassingStationCollection; import com.jcdm.main.da.passingStationCollection.service.impl.DaPassingStationCollectionServiceImpl; import com.jcdm.main.plcserver.conf.OPCElement; import com.jcdm.main.rm.repairRecord.domain.RmRepairRecord; import com.jcdm.main.rm.repairRecord.service.IRmRepairRecordService; import com.kangaroohy.milo.model.ReadWriteEntity; import com.kangaroohy.milo.runner.subscription.SubscriptionCallback; import com.kangaroohy.milo.service.MiloService; import javafx.animation.Timeline; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.sql.Time; import java.time.LocalDateTime; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Slf4j @Component public class OPCUaSubscription implements SubscriptionCallback { public static MiloService miloService; public IDaCollectionParamConfService collectionParamConfService; public IDaParamCollectionService daParamCollectionService; public DaPassingStationCollectionServiceImpl passingStationCollectionServiceImpl; public List lists; public static final HashMap map = new HashMap<>(); public IBsOrderSchedulingService bsOrderSchedulingService; public IRmRepairRecordService rmRepairRecordService; public IBsTechnologyRouteChildInfoService bsTechnologyRouteChildInfoService; public HashMap> allCollectParamList = new HashMap<>(); public OPCUaSubscription(MiloService miloService, IDaCollectionParamConfService collectionParamConfService, IDaParamCollectionService daParamCollectionService, DaPassingStationCollectionServiceImpl passingStationCollectionServiceImpl, IBsOrderSchedulingService bsOrderSchedulingService, List lists, IRmRepairRecordService rmRepairRecordService, IBsTechnologyRouteChildInfoService bsTechnologyRouteChildInfoService) { OPCUaSubscription.miloService = miloService; this.collectionParamConfService = collectionParamConfService; this.daParamCollectionService = daParamCollectionService; this.passingStationCollectionServiceImpl = passingStationCollectionServiceImpl; this.bsOrderSchedulingService = bsOrderSchedulingService; this.lists = lists; this.rmRepairRecordService = rmRepairRecordService; this.bsTechnologyRouteChildInfoService = bsTechnologyRouteChildInfoService; } @Override public void onSubscribe(String identifier, Object value) { String ecpStr = "";//异常记录标记 try { if(null != value && "1".equals(value.toString())) { // if (OPCElement.OP121_ZZ_CODE_CHECK.equals(identifier)){ // rework("2V91Y RD25D080",identifier); // } //1、检索SN号 //2、过站参数采集 //3、扫码枪数据回传 List collect1 = lists.stream().filter(x -> OPCElement.SN_CHECK.equals(x.getrFunction())) .map(DaOpcuaConfig::getNode).collect(Collectors.toList()); List collect2 = lists.stream().filter(x -> OPCElement.SAVE_DATA.equals(x.getrFunction())) .map(DaOpcuaConfig::getNode).collect(Collectors.toList()); if (collect1.contains(identifier)){ log.info("-------监听到,{}的CODE_CHECK的信号",identifier); log.info("-------time--------------,{}",LocalDateTime.now()); //sn this.SNRetrieval(identifier,value.toString()); if (identifier.equals(OPCElement.OP120_ZZ_CODE_CHECK) && "1".equals(value.toString())){ //总装上线扫码传输数据 log.info("-------监听到,{}的扫码枪扫码的CODE_CHECK的信号",identifier); scannerGunMessage(); } } if (collect2.contains(identifier)){ if ("1".equals(value.toString())){ log.info("-------监听到,{}的SAVE_REQUEST_LAST的信号",identifier); log.info("-------time--------------,{}",LocalDateTime.now()); //save this.SaveData(identifier); } } } } catch (Exception e) { System.out.println(e.getMessage()); } finally { if (!"".equals(ecpStr)) { System.out.println(ecpStr + "\r\n"); } } } private void scannerGunMessage() throws Exception { String[] parts = OPCElement.OP120_ZZ_CODE_CHECK.split("[.]"); Object SNCodeObject = miloService.readFromOpcUa(parts[0] + "." + parts[1] + ".Code1").getValue(); if (null == SNCodeObject){ SNCodeObject = miloService.readFromOpcUa(parts[0] + "." + parts[1] + ".Code").getValue(); } if (null != SNCodeObject){ String SNCode = SNCodeObject.toString(); passingStationCollectionServiceImpl.sendMessage(SNCode); } } public void SNRetrieval(String Node, String value) throws Exception { String[] parts = Node.split("[.]"); if(value.equals("1")) { //SN号检索 Object SNCodeObject = miloService.readFromOpcUa(parts[0] + "." + parts[1] + ".Code").getValue(); if(null != SNCodeObject) { String SNCode=SNCodeObject.toString(); // String a=passingStationCollectionServiceImpl.SelectSN(SNCode,parts[1]); String a; BsOrderScheduling bsOrderSchedulingQuery = new BsOrderScheduling(); bsOrderSchedulingQuery.setEngineNo(SNCode); List queryOrderList = bsOrderSchedulingService.selectBsOrderSchedulingList(bsOrderSchedulingQuery); if (CollUtil.isNotEmpty(queryOrderList)){ a = "1"; }else { a = "4"; } //如果是返修工位需要传输返修工位号 List daPassingStationCollections = new ArrayList<>(); List rmRepairRecords = new ArrayList<>(); if (OPCElement.OP465_ZZ_CODE_CHECK.equals(Node) || OPCElement.OP355_ZZ_CODE_CHECK.equals(Node) || OPCElement.OP695_ZZ_CODE_CHECK.equals(Node) || OPCElement.OP755_ZZ_CODE_CHECK.equals(Node)){ //过站记录 DaPassingStationCollection PassingStationCollection=new DaPassingStationCollection(); PassingStationCollection.setSfcCode(SNCode); daPassingStationCollections = passingStationCollectionServiceImpl.selectDaPassingStationCollectionList(PassingStationCollection); if (CollUtil.isNotEmpty(daPassingStationCollections)){ DaPassingStationCollection lastOne = daPassingStationCollections.get(daPassingStationCollections.size() - 1); String outRsSign = lastOne.getOutRsSign(); if ("合格".equals(outRsSign)){ a = "1"; }else { a = "2"; } } RmRepairRecord rmRepairRecord = new RmRepairRecord(); rmRepairRecord.setBoxCode(SNCode); rmRepairRecords = rmRepairRecordService.selectRmRepairRecordList(rmRepairRecord); if (CollUtil.isNotEmpty(rmRepairRecords)){ a = "1"; } } log.info("-----返回codeCheckFeed-----,{}",a); // String a="1"; // 1:OK可生产 2:NG不可生产 3:NG可返工 4:PC检索失败(无记录)5:PC检索失败(软件) if (StrUtil.isNotBlank(a)){ int input = Integer.parseInt(a); ReadWriteEntity entity = new ReadWriteEntity(parts[0]+"."+parts[1]+".CodeCheckFeed", input); log.info("-------监听到,{}的CodeCheck的信号",Node); miloService.writeToOpcByte(entity); log.info("监听到返回codecheckfeed信号,{}",entity); //首站传输订单号 if (OPCElement.OP050_HX_CODE_CHECK.equals(Node)){ //查询订单号 BsOrderScheduling bsOrderScheduling = new BsOrderScheduling(); bsOrderScheduling.setEngineNo(SNCode); List tempList = bsOrderSchedulingService.selectBsOrderSchedulingList(bsOrderScheduling); String orderNum = ""; if (CollUtil.isNotEmpty(tempList)){ BsOrderScheduling bsOrderScheduling1 = tempList.get(0); orderNum = bsOrderScheduling1.getOrderNo(); } ReadWriteEntity entity2 = new ReadWriteEntity(parts[0]+"."+parts[1]+".OrderNumber", orderNum); miloService.writeToOpcUa(entity2); } //如果是返修工位需要传输返修工位号 if (OPCElement.OP465_ZZ_CODE_CHECK.equals(Node) || OPCElement.OP355_ZZ_CODE_CHECK.equals(Node) || OPCElement.OP695_ZZ_CODE_CHECK.equals(Node) || OPCElement.OP755_ZZ_CODE_CHECK.equals(Node)){ rework(SNCode,Node,daPassingStationCollections,rmRepairRecords); } System.out.println(entity); } } } } private void rework(String SNCode,String Node,List daPassingStationCollections,List rmRepairRecords) throws Exception{ BsOrderScheduling bsOrderScheduling = new BsOrderScheduling(); bsOrderScheduling.setEngineNo(SNCode); List allProcessCoed = new ArrayList<>(); List bsTechnologyRouteChildInfos = new ArrayList<>(); List collect = bsOrderSchedulingService.selectBsOrderSchedulingList(bsOrderScheduling).stream().map(BsOrderScheduling::getModel).collect(Collectors.toList()); if (CollUtil.isNotEmpty(collect)){ String s = collect.get(0); //查找次机型的完整工序 bsTechnologyRouteChildInfos = bsTechnologyRouteChildInfoService.selectAllTechnologyRouteByProductCode(s); if (CollUtil.isNotEmpty(bsTechnologyRouteChildInfos)){ allProcessCoed = bsTechnologyRouteChildInfos.stream().map(BsTechnologyRouteChildInfo::getProcessesCode).collect(Collectors.toList()); } } // RmRepairRecord rmRepairRecord = new RmRepairRecord(); // rmRepairRecord.setBoxCode(SNCode); List writeList = new ArrayList<>(); // List rmRepairRecords = rmRepairRecordService.selectRmRepairRecordList(rmRepairRecord); //过站记录 // DaPassingStationCollection PassingStationCollection=new DaPassingStationCollection(); // PassingStationCollection.setSfcCode(SNCode); //过站记录 // List daPassingStationCollections = passingStationCollectionServiceImpl.selectDaPassingStationCollectionList(PassingStationCollection); //所有反工工位 List collect1 = rmRepairRecords.stream().map(RmRepairRecord::getProcessesCode).collect(Collectors.toList()); if (CollUtil.isNotEmpty(collect1)){ //查询出所有需要返修工位的最小op块 Integer minOP = 0; if (CollUtil.isNotEmpty(collect1)){ List sortList = new ArrayList<>(); collect1.stream().forEach(x ->{ String op = x.replace("OP", ""); if (StrUtil.isNotBlank(op)){ int i = Integer.parseInt(op); sortList.add(i); } }); if (CollUtil.isNotEmpty(sortList)){ List collect2 = sortList.stream().filter(Objects::nonNull).sorted().collect(Collectors.toList()); minOP = collect2.get(0); } } //获取过站记录的最大工位 String maxCode = null; if (CollUtil.isNotEmpty(daPassingStationCollections)){ DaPassingStationCollection lastOne = daPassingStationCollections.get(daPassingStationCollections.size() - 1); maxCode = lastOne.getLocationCode(); } //所有放行工位 List passStation = new ArrayList<>(); //所有生产工位 List productStation = new ArrayList<>(); //最大工位编号 Integer maxCodeNum = 0; if (StrUtil.isNotEmpty(maxCode)){ String finalMaxCode = maxCode; //获取当前工位对应工步号 List collect2 = bsTechnologyRouteChildInfos.stream() .filter(x -> x.getProcessesCode().equals(finalMaxCode)) .map(BsTechnologyRouteChildInfo::getStepNo).collect(Collectors.toList()); if (CollUtil.isNotEmpty(collect2)){ String s = collect2.get(0); if (StrUtil.isNotBlank(s)){ maxCodeNum = Integer.parseInt(s); } } if (CollUtil.isNotEmpty(bsTechnologyRouteChildInfos)){ bsTechnologyRouteChildInfos.forEach(x -> { x.setStepNoNum(Integer.parseInt(x.getStepNo())); }); Integer finalMaxCodeNum = maxCodeNum; //勾选的返修工位中最大的工位之后的工位----1 List collect3 = bsTechnologyRouteChildInfos.stream() .filter(x -> x.getStepNoNum() >= finalMaxCodeNum).collect(Collectors.toList()); if (CollUtil.isNotEmpty(collect3)){ //需要生产 productStation.addAll(collect3.stream().map(BsTechnologyRouteChildInfo::getProcessesCode).collect(Collectors.toList())); } //从第一个工位到返修的最大工位之间, //勾选了返修标记的需要生产---1,未勾选的不生产---2 productStation.addAll(collect1); } } if (CollUtil.isNotEmpty(productStation)){ List collect2 = allProcessCoed.stream().filter(x -> !productStation.contains(x)).collect(Collectors.toList()); passStation.addAll(collect2); } String[] parts = Node.split("[.]"); String par = parts[0]+"."+parts[1]; if (CollUtil.isNotEmpty(passStation)){ passStation.forEach(x -> { ReadWriteEntity readWriteEntity = new ReadWriteEntity(); readWriteEntity.setIdentifier(par+"."+x); readWriteEntity.setValue(2); writeList.add(readWriteEntity); }); } if (CollUtil.isNotEmpty(productStation)){ productStation.forEach(x -> { ReadWriteEntity readWriteEntity = new ReadWriteEntity(); readWriteEntity.setIdentifier(par+"."+x); readWriteEntity.setValue(1); writeList.add(readWriteEntity); }); } ReadWriteEntity readWriteEntity = new ReadWriteEntity(); readWriteEntity.setIdentifier(parts[0]+"."+parts[1]+".Repair_sign"); readWriteEntity.setValue(minOP); miloService.writeToOpcShort(readWriteEntity); miloService.writeToOpcByte(writeList); log.info("返修写入:,{}",writeList); } } public void SaveData(String Node) throws Exception { String[] parts = Node.split("[.]"); Object SNCodeObject = miloService.readFromOpcUa(parts[0] + "." + parts[1] + ".Code1").getValue(); if (null == SNCodeObject){ SNCodeObject = miloService.readFromOpcUa(parts[0] + "." + parts[1] + ".Code").getValue(); } if(null != SNCodeObject) { String SNCode = SNCodeObject.toString(); Object object = miloService.readFromOpcUa(parts[0] + "." + parts[1] + ".Runtime").getValue(); String gatherAddress = parts[0] + "." + parts[1]; List list = new ArrayList<>(); if (allCollectParamList.containsKey(gatherAddress)){ list = allCollectParamList.get(gatherAddress); }else { DaCollectionParamConf daCollectionParamConf = new DaCollectionParamConf(); daCollectionParamConf.setGatherAddress(gatherAddress); daCollectionParamConf.setRemarks("1"); list = collectionParamConfService.selectDaCollectionParamConfList(daCollectionParamConf); if (CollUtil.isNotEmpty(list)){ //加入hashmap allCollectParamList.put(gatherAddress,list); } } List nodeIdList = list.stream().map(info -> { String nodeid = info.getGatherAddress(); return nodeid; }).collect(Collectors.toList()); List readWriteEntityList = new ArrayList<>(); if(CollUtil.isNotEmpty(nodeIdList)){ long time1 = new Date().getTime(); readWriteEntityList = miloService.readFromOpcUa(nodeIdList); long time2 = new Date().getTime(); log.info("读取点位花费时间:{},",time2-time1); } //返回plc保存成功 if (parts.length==3){ if ("SaveRequest".equals(parts[2])){ ReadWriteEntity entity = new ReadWriteEntity(parts[0] + "." + parts[1] + ".SaveFeed", 1); miloService.writeToOpcByte(entity); }else if ("SaveRequestLast".equals(parts[2])){ ReadWriteEntity entity = new ReadWriteEntity(parts[0] + "." + parts[1] + ".SaveFeedLast", 1); miloService.writeToOpcByte(entity); } log.info("-------请求返回,{}的SaveFeedLast的信号",Node); log.info("-------请求返回-----,{}",LocalDateTime.now()); } List daParamCollectionlist = new ArrayList<>(); if (CollUtil.isNotEmpty(nodeIdList)){ for(int i=0;i