diff --git a/web/src/main/java/com/zhehekeji/web/controller/MonitorController.java b/web/src/main/java/com/zhehekeji/web/controller/MonitorController.java new file mode 100644 index 0000000..4a33324 --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/controller/MonitorController.java @@ -0,0 +1,153 @@ +package com.zhehekeji.web.controller; + +import com.alibaba.fastjson.JSONObject; +import com.zhehekeji.common.util.FileUtil; +import com.zhehekeji.core.pojo.Result; +import com.zhehekeji.web.entity.Stock; +import com.zhehekeji.web.pojo.Cmd; +import com.zhehekeji.web.service.GoodsActionTimes; +import com.zhehekeji.web.service.PlcCmdInfo; +import com.zhehekeji.web.service.PlcService; +import com.zhehekeji.web.service.ksec.KsecDataInfo; +import com.zhehekeji.web.service.ksec.KsecInfo; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.StringUtils; +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 javax.annotation.Resource; +import java.nio.charset.Charset; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + + +@Api(value = "monitor",tags = "监控接口") +@RestController +@RequestMapping("/monitor") +@Slf4j +public class MonitorController { + + @Resource + private PlcService plcService; + private static final Logger tcpLogger = LoggerFactory.getLogger("tcp"); + + private static String lastLotnum; + + private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(7,21,30, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(20000)); + + @PostMapping("/task") + public Result monitorTask(@RequestBody KsecInfo ksecInfo){ + KescRunnable kescRunnable = new KescRunnable(ksecInfo,plcService); + threadPoolExecutor.execute(kescRunnable); + return Result.success(); + } + + public static class KescRunnable implements Runnable{ + + private KsecInfo ksecInfo; + + private PlcService plcService; + + public KescRunnable(KsecInfo ksecInfo,PlcService plcService){ + this.ksecInfo = ksecInfo; + this.plcService = plcService; + } + + @Override + public void run() { + tcpLogger.info("{}",JSONObject.toJSONString(ksecInfo)); + KsecDataInfo dataInfo = ksecInfo.getData(); + String lotnum = dataInfo.getLotnum(); + PlcCmdInfo plcCmdInfo = null; + String srmNumber = dataInfo.getSRMNumber(); + String cmdName = dataInfo.getCmdName();; + if(dataInfo != null){ + + plcCmdInfo = new PlcCmdInfo(dataInfo.getSRMNumber(), dataInfo.getTaskId(), dataInfo.getFromSide(), dataInfo.getFromDirection(), dataInfo.getFromColumn(), dataInfo.getFromRow(), dataInfo.getFromSeparation(),dataInfo.getToSide(), dataInfo.getToDirection(), dataInfo.getToColumn(), dataInfo.getToRow(),dataInfo.getToSeparation(),lotnum); + } + if (Cmd.A.name().equals(ksecInfo.getType())) { + //心跳 + log.debug("receieve heart "); + } else if (Cmd.B.name().equals(ksecInfo.getType())) { + + //任务 + if (Cmd.B1.name().equals(cmdName)) { + //任务开始 旋转到原点位 + plcService.gyrateCamera(plcCmdInfo,Cmd.C5.name()); + plcService.orderStart(plcCmdInfo); + + } else if (Cmd.B2.name().equals(cmdName)) { + plcService.gyrateCamera(plcCmdInfo,Cmd.C5.name()); + plcService.orderStop(plcCmdInfo); + } + } else if (Cmd.C.name().equals(ksecInfo.getType())) { + + //动作 + String code = dataInfo.getCmdName(); + log.info("action code,{},orderInfo:{}", code, plcCmdInfo.toString()); + if (Cmd.isBaseAction(code)) { + //执行动作,需要保存执行到第几步了 + Integer times = GoodsActionTimes.put(plcCmdInfo.getOrderNum()); + plcCmdInfo.setTimes(times); + code = code + "-" + plcCmdInfo.getLeftRightStr(times) + plcCmdInfo.getInOutStr(times); + //执行动作 + try { + plcService.action(plcCmdInfo, times, code); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }else { + log.info("other C code :{}",code); + } + } else if (Cmd.D.name().equals(ksecInfo.getType())) { + + String code = dataInfo.getCmdName(); + if(code.equals(Cmd.D1.name())){ + log.info("plcId:{},warn start",plcCmdInfo.getPlcId()); + //根据告警code转动camera + String warnCode = dataInfo.getWarnCode(); + if(!StringUtils.isEmpty(warnCode)){ + String warnCode0 = Cmd.D1.name()+"-"+warnCode.split(",")[0]; + plcService.warnAction(plcCmdInfo,warnCode0); + } + plcService.warnStart(plcCmdInfo.getPlcId(),dataInfo.getWarnCode()); + }else if(code.equals(Cmd.D2.name())){ + log.info("plcId:{},warn stop",plcCmdInfo.getPlcId()); + plcService.warnStop(plcCmdInfo.getPlcId()); + }else { + log.info("other D code :{}",code); + } + } else if (Cmd.E.name().equals(ksecInfo.getType())) { + + //盘点 + //转球机到盘点位 然后拍照 + + if(!StringUtils.isEmpty(lotnum) && !lotnum.equals(lastLotnum)){ + //需要把stock表truncate + FileUtil.save(lotnum,"lastLotnum"); + + plcService.truncateStock(); + lastLotnum = lotnum; + } + plcCmdInfo.setTimes(1); + Stock stock = plcService.check(plcCmdInfo,ksecInfo.getData().getCmdName(), dataInfo.getCode(), dataInfo.getWmsCode()); + if(stock.getStatus() == 2){ + ksecInfo.getData().setStatus(1); + ksecInfo.getData().setCode(stock.getTrayCode()); + }else { + ksecInfo.getData().setStatus(0); + ksecInfo.getData().setCode(stock.getTrayCode()); + } + + } + } + } +} diff --git a/web/src/main/java/com/zhehekeji/web/service/PlcService.java b/web/src/main/java/com/zhehekeji/web/service/PlcService.java index eb19a43..33aeca1 100644 --- a/web/src/main/java/com/zhehekeji/web/service/PlcService.java +++ b/web/src/main/java/com/zhehekeji/web/service/PlcService.java @@ -272,7 +272,6 @@ public class PlcService { } //转向原点位 if(times == 2){ - if(street.getCamera2Id() != null){ gyrateCameraByCodeTimeLater(street.getCamera2Id(),"C5",configProperties.getCameraConfig().getC2OutDelayCaptureTime()+500); } @@ -583,7 +582,7 @@ public class PlcService { @Resource private LightSourceMapper lightSourceMapper; - public Boolean check(PlcCmdInfo plcCmdInfo,String cmdCode,String wmsCode,String wmsTrayCode){ + public Stock check(PlcCmdInfo plcCmdInfo,String cmdCode,String wmsCode,String wmsTrayCode){ long startTime = System.currentTimeMillis(); Street street = streetService.getStreetByPlcId(plcCmdInfo.getPlcId()); @@ -592,101 +591,48 @@ public class PlcService { lightSources.forEach(lightSource -> { HikControlSocket.openLight(lightSource.getIp(),lightSource.getPort(),configProperties.getLightSource().getIndex(),1); }); - Integer cameraId = getCameraByPlcCmd(plcCmdInfo,plcCmdInfo.getLeftRight1()); - - if(plcCmdInfo.getSeparation1() == 1 && configProperties.getScanCodeMode().getTray() == 2){ - //内测 - String c = cmdCode + "-" + plcCmdInfo.getLeftRightStr(1) + "-IN"; - log.info("camera ptz"+c); - gyrateCameraByCode(cameraId, c); - }else { - gyrateCameraByCode(cameraId, cmdCode); - try { - Thread.sleep(configProperties.getCameraConfig().getDelayCaptureTime()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - String path = PathUtil.createFileNameByRowColumn("jpg",cameraId,plcCmdInfo.getRow1(),plcCmdInfo.getColumn1()); - cameraCapture(cameraId,false,null,path); //托盘码 String trayCode = null; Boolean trayCheck = Boolean.TRUE; //如果是用扫码枪 扫 托盘码,就直接扫 //if(configProperties.getScanCodeMode().getTray() == 2){ SensorGun sensorGun = sensorService.getSensorByPlc(street.getId(),plcCmdInfo.getLeftRight1()); - if(plcCmdInfo.getSeparation1() == 1 && configProperties.getScanCodeMode().getTray() == 2){ - //托盘使用sick扫码枪 - - if(sensorGun == null){ - trayCode = "识别异常"; - trayCheck = Boolean.FALSE; - log.error("no sensor gun config in database ,street id:{},direction:{}",street.getId(),plcCmdInfo.getLeftRight1()); - }else { - trayCode = SickSocket.readOCR(sensorGun.getIp(),sensorGun.getPort()); - log.info("sensor tray code:{}",trayCode); - if("".equals(wmsTrayCode)){ - //托盘码为空,无货物 - //只要扫码枪未识别出条码,即认为盘点正确 - if(StringUtils.isEmpty(trayCode) || trayCode.equals("NoRead")){ - trayCode = ""; - trayCheck = Boolean.TRUE; - }else { - trayCode = "识别异常"; - trayCheck = Boolean.FALSE; - log.warn("sick ocr error:{}",trayCode); - } - }else { - if(StringUtils.isEmpty(trayCode) || trayCode.equals("NoRead")){ - trayCode = "识别异常"; - trayCheck = Boolean.FALSE; - log.warn("sick ocr error:{}",trayCode); - }else { - trayCheck = wmsTrayCode.equals(trayCode); - } - } - - } - - }else if(configProperties.getScanCodeMode().getTray() == 3){ - //RFID - RFID rfid = rfidService.getRFIDByPlc(street.getId()); - } - OrderInfo orderInfo = new OrderInfo(street,plcCmdInfo,1,cmdCode); - Stock stock = stockMapper.getByShelveIdAndRowColumn(orderInfo.getShelveId(),orderInfo.getRow(),orderInfo.getColumn()); - String scanCode = null; - Boolean codeCheck = Boolean.TRUE; - Boolean trayCodeCheck = Boolean.TRUE; - //货物使用球机扫码 - - if(configProperties.getScanCodeMode().getTray() == 2 && plcCmdInfo.getSeparation1() == 2){ - //托盘使用球机扫码 + if(sensorGun == null){ + trayCode = "识别异常"; + trayCheck = Boolean.FALSE; + log.error("no sensor gun config in database ,street id:{},direction:{}",street.getId(),plcCmdInfo.getLeftRight1()); + }else { + trayCode = SickSocket.readOCR(sensorGun.getIp(),sensorGun.getPort()); + log.info("sensor tray code:{}",trayCode); if("".equals(wmsTrayCode)){ - //空货物的处理 - //如果系统货物为空,则只要扫码识别未出结果,就认为无货物 - trayCode = BarcodeDetector.detectBestCodeUntilOK(configProperties.getSavePath().getMediaPath()+path,configProperties.getScanCodeMode().getTrayCodeTypes()); - log.info("tray code:{},sys trayCode:{}",trayCode,wmsTrayCode); - if(StringUtils.isEmpty(trayCode)|| trayCode.equals("Unrecognized")){ - trayCheck = Boolean.TRUE; + //托盘码为空,无货物 + //只要扫码枪未识别出条码,即认为盘点正确 + if(StringUtils.isEmpty(trayCode) || trayCode.equals("NoRead")){ trayCode = ""; + trayCheck = Boolean.TRUE; }else { - trayCheck = wmsTrayCode.equals(trayCode); + trayCode = "识别异常"; + trayCheck = Boolean.FALSE; + log.warn("sick ocr error:{}",trayCode); } }else { - trayCode = BarcodeDetector.detectBestCodeUntilOK(configProperties.getSavePath().getMediaPath()+path,configProperties.getScanCodeMode().getTrayCodeTypes()); - if(StringUtils.isEmpty(trayCode)){ - log.error("row:{},cloumn:{}",plcCmdInfo.getRow1(),plcCmdInfo.getColumn1()); - log.error("detectBestBarCode:{}",trayCode); + if(StringUtils.isEmpty(trayCode) || trayCode.equals("NoRead")){ trayCode = "识别异常"; trayCheck = Boolean.FALSE; + log.warn("sick ocr error:{}",trayCode); }else { trayCheck = wmsTrayCode.equals(trayCode); } } } + OrderInfo orderInfo = new OrderInfo(street,plcCmdInfo,1,cmdCode); + Stock stock = stockMapper.getByShelveIdAndRowColumn(orderInfo.getShelveId(),orderInfo.getRow(),orderInfo.getColumn()); + String scanCode = null; + Boolean codeCheck = Boolean.TRUE; + Boolean trayCodeCheck = Boolean.TRUE; + log.info("code:{}",scanCode); //核对异常 Integer status = 1; @@ -695,13 +641,13 @@ public class PlcService { status = 2; } if(stock == null){ - stock = new Stock(null,null,plcCmdInfo.getOrderNum(),plcCmdInfo.getLotnum(),scanCode, null,null,wmsCode,null,null,wmsTrayCode,trayCode,orderInfo.getShelveId(),orderInfo.getRow(),orderInfo.getColumn(),status,null,null,path, LocalDateTime.now()); + stock = new Stock(null,null,plcCmdInfo.getOrderNum(),plcCmdInfo.getLotnum(),scanCode, null,null,wmsCode,null,null,wmsTrayCode,trayCode,orderInfo.getShelveId(),orderInfo.getRow(),orderInfo.getColumn(),status,null,null,"", LocalDateTime.now()); stockMapper.insert(stock); }else { stock.setStatus(status); stock.setLotnum(plcCmdInfo.getLotnum()); stock.setExportTime(LocalDateTime.now()); - stock.setCheckPic(path); + //stock.setCheckPic(path); stock.setCheckNum(plcCmdInfo.getOrderNum()); stock.setTrayCode(trayCode); stock.setWmsTrayCode(wmsTrayCode); @@ -716,7 +662,7 @@ public class PlcService { long end = System.currentTimeMillis(); long s = end - startTime; log.info("time:{}millisecond",s); - return true; + return stock; } public void checkLog(Stock stock){ CheckLog checkLog = new CheckLog(); diff --git a/web/src/main/java/com/zhehekeji/web/service/ksec/KsecDataInfo.java b/web/src/main/java/com/zhehekeji/web/service/ksec/KsecDataInfo.java index 90ac787..9508fbe 100644 --- a/web/src/main/java/com/zhehekeji/web/service/ksec/KsecDataInfo.java +++ b/web/src/main/java/com/zhehekeji/web/service/ksec/KsecDataInfo.java @@ -35,9 +35,9 @@ public class KsecDataInfo { private String warnCode; - private Integer ackStatus; + private Integer status; - private String trayCode; + private String wmsCode; /** * 盘点批次号 diff --git a/web/src/main/java/com/zhehekeji/web/service/ksec/KsecDecoder.java b/web/src/main/java/com/zhehekeji/web/service/ksec/KsecDecoder.java index 5f0473d..159b466 100644 --- a/web/src/main/java/com/zhehekeji/web/service/ksec/KsecDecoder.java +++ b/web/src/main/java/com/zhehekeji/web/service/ksec/KsecDecoder.java @@ -2,6 +2,7 @@ package com.zhehekeji.web.service.ksec; import com.alibaba.fastjson.JSONObject; import com.zhehekeji.common.util.FileUtil; +import com.zhehekeji.web.entity.Stock; import com.zhehekeji.web.pojo.Cmd; import com.zhehekeji.web.service.GoodsActionTimes; import com.zhehekeji.web.service.PlcCmdInfo; @@ -33,7 +34,7 @@ public class KsecDecoder extends DelimiterBasedFrameDecoder { private static String lastLotnum; - private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(7,21,30, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(20000)); + //private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(0,21,30, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(20000)); private PlcService plcService; @@ -49,8 +50,8 @@ public class KsecDecoder extends DelimiterBasedFrameDecoder { log.debug("no data"); return null; } - KescRunnable kescRunnable = new KescRunnable(in,ctx,plcService); - threadPoolExecutor.execute(kescRunnable); + //KescRunnable kescRunnable = new KescRunnable(in,ctx,plcService); + //threadPoolExecutor.execute(kescRunnable); return null; } @@ -109,35 +110,11 @@ public class KsecDecoder extends DelimiterBasedFrameDecoder { //任务 if (Cmd.B1.name().equals(cmdName)) { - //昆船盘点模式下也会发B1 ,但是不会发送B2 - //这里判断下,是否存在盘点批次号 若存在,既是盘点的B1,无需处理;若不存在lotnum,则是随行的B1 - if(StringUtils.isEmpty(dataInfo.getLotnum())){ - //任务开始 旋转到原点位 - plcService.gyrateCamera(plcCmdInfo,Cmd.C5.name()); - plcService.orderStart(plcCmdInfo); - }else { - log.info("check move"); - } + //任务开始 旋转到原点位 + plcService.gyrateCamera(plcCmdInfo,Cmd.C5.name()); + plcService.orderStart(plcCmdInfo); } else if (Cmd.B2.name().equals(cmdName)) { - //B2 C4 一起发的,需要停止等B2 - - //这里判断是不是双伸 - if(plcCmdInfo.getSeparation2() == 2){ - //深测货架延迟 - try { - Thread.sleep(plcService.getConfigProperties().getCameraConfig().getB2OutDelayTime()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - }else { - //浅侧延迟 - try { - Thread.sleep(plcService.getConfigProperties().getCameraConfig().getB2DelayTime()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } plcService.gyrateCamera(plcCmdInfo,Cmd.C5.name()); plcService.orderStop(plcCmdInfo); } @@ -162,23 +139,22 @@ public class KsecDecoder extends DelimiterBasedFrameDecoder { } } else if (Cmd.D.name().equals(ksecInfo.getType())) { - //柳州去掉告警 -// String code = dataInfo.getCmdName(); -// if(code.equals(Cmd.D1.name())){ -// log.info("plcId:{},warn start",plcCmdInfo.getPlcId()); -// //根据告警code转动camera -// String warnCode = dataInfo.getWarnCode(); -// if(!StringUtils.isEmpty(warnCode)){ -// String warnCode0 = Cmd.D1.name()+"-"+warnCode.split(",")[0]; -// plcService.warnAction(plcCmdInfo,warnCode0); -// } -// plcService.warnStart(plcCmdInfo.getPlcId(),dataInfo.getWarnCode()); -// }else if(code.equals(Cmd.D2.name())){ -// log.info("plcId:{},warn stop",plcCmdInfo.getPlcId()); -// plcService.warnStop(plcCmdInfo.getPlcId()); -// }else { -// log.info("other D code :{}",code); -// } + String code = dataInfo.getCmdName(); + if(code.equals(Cmd.D1.name())){ + log.info("plcId:{},warn start",plcCmdInfo.getPlcId()); + //根据告警code转动camera + String warnCode = dataInfo.getWarnCode(); + if(!StringUtils.isEmpty(warnCode)){ + String warnCode0 = Cmd.D1.name()+"-"+warnCode.split(",")[0]; + plcService.warnAction(plcCmdInfo,warnCode0); + } + plcService.warnStart(plcCmdInfo.getPlcId(),dataInfo.getWarnCode()); + }else if(code.equals(Cmd.D2.name())){ + log.info("plcId:{},warn stop",plcCmdInfo.getPlcId()); + plcService.warnStop(plcCmdInfo.getPlcId()); + }else { + log.info("other D code :{}",code); + } } else if (Cmd.E.name().equals(ksecInfo.getType())) { //盘点 @@ -192,11 +168,13 @@ public class KsecDecoder extends DelimiterBasedFrameDecoder { lastLotnum = lotnum; } plcCmdInfo.setTimes(1); - Boolean ok = plcService.check(plcCmdInfo,ksecInfo.getData().getCmdName(), dataInfo.getCode(), dataInfo.getTrayCode()); - if(ok){ - ksecInfo.getData().setAckStatus(1); + Stock stock = plcService.check(plcCmdInfo,ksecInfo.getData().getCmdName(), dataInfo.getCode(), dataInfo.getWmsCode()); + if(stock.getStatus() == 2){ + ksecInfo.getData().setStatus(1); + ksecInfo.getData().setCode(stock.getTrayCode()); }else { - ksecInfo.getData().setAckStatus(0); + ksecInfo.getData().setStatus(0); + ksecInfo.getData().setCode(stock.getTrayCode()); } ctx.channel().writeAndFlush(ksecInfo); } diff --git a/web/src/main/resources/application-dev.yml b/web/src/main/resources/application-dev.yml index 891de3c..bbeb6ca 100644 --- a/web/src/main/resources/application-dev.yml +++ b/web/src/main/resources/application-dev.yml @@ -34,10 +34,25 @@ cameraConfig: videoServer: 127.0.0.1:8083 #相机抓图延迟 毫秒,这个延迟是等待球机球机转动到位,然后拍照的 delayCaptureTime: 3500 + #随行模式下的相机抓图延迟 毫秒,这个延迟是等待球机球机转动到位,然后拍照的 + # 发了C1之后多久拍照 + C1DelayCaptureTime: 1500 + # 内侧货架 发了C2 之后多久拍照 + C2DelayCaptureTime: 1500 + # 外侧货架 发了C2 之后多久拍照 + C2OutDelayCaptureTime: 2500 + # 发了C3之后多久拍照 + C3DelayCaptureTime: 1500 + C4DelayCaptureTime: 1500 + C4OutDelayCaptureTime: 1500 + # 发了B2之后多久转原点位 + B2DelayTime: 2000 + # 外侧货架发了B2多久转原点位 + B2OutDelayTime: 2000 # 下载mp4延迟 海康的下载mp4需要2分钟 # 利珀延迟10s就可 # 单位毫秒 - delayDownloadMp4: 120000 + delayDownloadMp4: 10000 # ------------ # -----图片 mp4下载地址 savePath: