src/main/java/com/zy/asrs/entity/LocMast.java
@@ -189,9 +189,9 @@ private Integer fireStatus=0; /** * 产品状态{0:无,1:待测,2:测试中;3.测试完成;4.测试失败;5.静置中;6:静置完成;7:暂停测试;8:紧急出库;} * 产品状态{0:空闲,1:待测,2:测试中;3.测试完成;4.测试失败;} */ @ApiModelProperty(value= "产品状态{0:无,1:待测,2:测试中;3.测试完成;4.测试失败;5.静置中;6:静置完成;7:暂停测试;8:紧急出库;}") @ApiModelProperty(value= "产品状态{0:空闲,1:待测,2:测试中;3.测试完成;4.测试失败;}") @TableField("pack_status") private Integer packStatus; src/main/java/com/zy/asrs/entity/TestMast.java
@@ -56,9 +56,9 @@ private String userId; /** * 状态 0: 待申请 1: 申请中 2: 已复核;3.测试中;4 * 状态 0: 无货 1: 等待测试 2:测试中 3.测试完成;4.测试失败; */ @ApiModelProperty(value= "状态 0: 待申请 1: 申请中 2: 已复核 3:测试中 4:完成") @ApiModelProperty(value= "状态 0: 无货 1: 等待测试 2:测试中 3.测试完成;4.测试失败; ") private Integer status; /** src/main/java/com/zy/asrs/mapper/LocMastMapper.java
@@ -35,6 +35,6 @@ @Select("select count(*) as count from asr_loc_mast where 1=1 and loc_sts = 'O' and loc_type1 = #{locType1} and crn_no = #{crnNo}") Integer selectEmptyLocCount(@Param("locType1") Short locType1, @Param("crnNo") Integer crnNo); LocMast selectztgx(@Param("sts1") String sts1,@Param("sts2") String sts2,@Param("count") Integer count); LocMast selectztgx(@Param("sts1") String sts1,@Param("count") Integer count); } src/main/java/com/zy/asrs/service/LocMastService.java
@@ -49,9 +49,8 @@ /** * 查询在库和预约出库的测试库位 * @param sts1 F * @param sts2 R * @param count i * @return */ LocMast selectztgx(String sts1,String sts2,Integer count); LocMast selectztgx(String sts1,Integer count); } src/main/java/com/zy/asrs/service/impl/LocMastServiceImpl.java
@@ -53,7 +53,7 @@ return this.baseMapper.selectEmptyLocCount(locMast.getLocType1(), locMast.getCrnNo()) > 1; } @Override public LocMast selectztgx(String sts1,String sts2,Integer count){ return this.baseMapper.selectztgx(sts1,sts2,count); public LocMast selectztgx(String sts1,Integer count){ return this.baseMapper.selectztgx(sts1,count); } } src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -48,10 +48,7 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport; import springfox.documentation.spring.web.json.Json; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Set; import java.util.*; import java.util.stream.Collectors; @@ -152,59 +149,32 @@ errMsg = errMsg + "扫码失败"; back = true; } // 退回 if (back) { // led 异常显示 LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed()); if (ledThread != null) { MessageQueue.offer(SlaveType.Led, inSta.getLed(), new Task(3, errMsg)); } continue; } String barcode = barcodeThread.getBarcode(); if (!Cools.isEmpty(barcode) && !barcode.equals("00000000")) { log.info("{}号条码扫描器检测条码信息:{}", inSta.getBarcode(), barcode); if ("NG".endsWith(barcode) || "NoRead".equals(barcode)) { continue; } } else { // led 异常显示 // LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed()); // if (ledThread != null) { // String errorMsg = "扫码失败,请重试"; // MessageQueue.offer(SlaveType.Led, inSta.getLed(), new Task(3, errorMsg)); // } continue; } if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isInEnable() && !staProtocol.isEmptyMk() && (staProtocol.getWorkNo() >= 9992 && staProtocol.getWorkNo() <= 9999) && !staProtocol.isEmptyMk() && (staProtocol.getWorkNo() >= 9990 && staProtocol.getWorkNo() <= 9999) && staProtocol.isPakMk()) {// && !Cools.isEmpty(barcode)) { // if(Cools.isEmpty(barcode) || "NG".endsWith(barcode) || "NoRead".equals(barcode)) { // log.info("{}号条码扫描器检测条码信息:{}", inSta.getBarcode(), barcode); // //条码为空或者不符合,退库到172站点 // staProtocol.setWorkNo((short)9999); // staProtocol.setStaNo((short)172); // devpThread.setPakMk(staProtocol.getSiteId(), false); // boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol)); // if (!result) { // throw new CoolException("更新plc站点信息失败"); // } // continue; // } // 退回 if (back ||(!Cools.isEmpty(barcode) && barcode.equals("00000000"))) { staProtocol.setWorkNo((short) 9999); staProtocol.setStaNo(inSta.getBackSta().shortValue()); devpThread.setPakMk(staProtocol.getSiteId(), false); boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol)); // led 异常显示 LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed()); if (ledThread != null) { MessageQueue.offer(SlaveType.Led, inSta.getLed(), new Task(3, errMsg)); } continue; } // 判断重复工作档 WrkMast wrkMast = wrkMastMapper.selectPakInStep1(inSta.getStaNo(), barcode); if (wrkMast != null) { News.error("工作档中已存在该站状态为( 2.设备上走 )的数据,工作号={}", wrkMast.getWrkNo()); continue; } // 获取入库通知档 List<WaitPakin> waitPakins = waitPakinMapper.selectList(new EntityWrapper<WaitPakin>().eq("zpallet", barcode).eq("io_status", "N")); if (waitPakins.isEmpty()) { log.error("无此入库条码数据。条码号={}", barcode); continue; } @@ -216,7 +186,6 @@ param.setIoType(1); param.setSourceStaNo(inSta.getStaNo()); param.setLocType1(locTypeDto.getLocType1()); // param.setPackNo(pack); String response = new HttpHandler.Builder() .setUri(wmsUrl) .setPath("/rpc/pakin/loc/v1") @@ -809,9 +778,6 @@ staProtocol = staProtocol.clone(); } // // 入出库模式判断 // if (devpThread.ioMode != IoModeType.PAKOUT_MODE) { continue; } // 查询站点详细信息 BasDevp staDetl = basDevpService.selectById(crnStn.getStaNo()); if (staDetl == null) { @@ -831,11 +797,6 @@ // 判断堆垛机出库站状态 if (staProtocol.isAutoing() && !staProtocol.isLoading() && staDetl.getCanouting() != null && staDetl.getCanouting().equals("Y") && staProtocol.getWorkNo() == 0 && staProtocol.isOutEnable()) { //测试库位出库必须要按启动按钮才能出库 if ((wrkMast.getStaNo() == 206 || wrkMast.getStaNo() == 1000) && locMast.getCtnKind() == 0) { News.error("出库 ===>> 等待启动出库按钮", wrkMast); continue; } // 命令下发区 -------------------------------------------------------------------------- // 堆垛机控制过滤 @@ -1051,30 +1012,22 @@ WrkMast wrkMast = null; if (Cools.isEmpty(wrkMasts)) { return; }else { wrkMast = wrkMasts.get(0); } //先查测试库位转OK或者NG库位按了按钮的 for (WrkMast wm : wrkMasts) { LocMast sourceSta1 = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", wm.getSourceLocNo())); if (!Cools.isEmpty(sourceSta1.getCtnKind())) { if (sourceSta1.getCtnKind() == 1) { wrkMast = wm; break; } } } //后查等待库位转测试库位 if (Cools.isEmpty(wrkMast)) { for (WrkMast wm : wrkMasts) { LocMast sourceSta1 = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", wm.getSourceLocNo())); if (sourceSta1.getLocType1() == 3) { wrkMast = wm; } } } //都没有满足条件的,跳过移库 if (Cools.isEmpty(wrkMast)) { return; } // //后查等待库位转测试库位 // if (Cools.isEmpty(wrkMast)) { // for (WrkMast wm : wrkMasts) { // LocMast sourceSta1 = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", wm.getSourceLocNo())); // if (sourceSta1.getLocType1() == 3) { // wrkMast = wm; // } // } // } // //都没有满足条件的,跳过移库 // if (Cools.isEmpty(wrkMast)) { // return; // } // 获取源库位信息 LocMast sourceSta = locMastService.selectById(wrkMast.getSourceLocNo()); @@ -1430,7 +1383,8 @@ * 出库 ===>> 工作档信息写入led显示器 */ @Async public synchronized void ledExecute() { public synchronized void ledExecute(Integer mark) { for (LedSlave led : slaveProperties.getLed()) { // 获取输送线plc线程 DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, led.getDevpPlcId()); @@ -1441,16 +1395,18 @@ for (Integer staNo : led.getStaArr()) { // 获取叉车站点 StaProtocol staProtocol = devpThread.getStation().get(staNo); if (null == staProtocol || null == staProtocol.getWorkNo() || 0 == staProtocol.getWorkNo()) { if (null == staProtocol || null == staProtocol.getWorkNo() || 0 == staProtocol.getWorkNo() || !staProtocol.isLoading()) { continue; } else { staProtocol = staProtocol.clone(); } // 获取工作档数据 WrkMast wrkMast = wrkMastMapper.selectById(staProtocol.getWorkNo()); // if (null == wrkMast || wrkMast.getWrkSts() < 14 || wrkMast.getIoType() < 100) { continue; } if (null == wrkMast) { continue; } log.info(""+mark+" - 0"+" - 开始执行:出库 ===>> 工作档信息写入led显示器"); wrkMasts.add(wrkMast); // 组装命令 LedCommand ledCommand = new LedCommand(); @@ -1481,39 +1437,18 @@ ledCommand.setEmptyMk(true); break; default: News.error("任务入出库类型错误!!![工作号:{}] [入出库类型:{}]", wrkMast.getWrkNo(), wrkMast.getIoType()); News.error(""+mark+" - 1"+" - 任务入出库类型错误!!![工作号:{}] [入出库类型:{}]", wrkMast.getWrkNo(), wrkMast.getIoType()); break; } ledCommand.setSourceLocNo(wrkMast.getSourceLocNo()); ledCommand.setLocNo(wrkMast.getLocNo()); ledCommand.setStaNo(wrkMast.getStaNo()); ledCommand.setBarcode(wrkMast.getBarcode()); // ledCommand.setSourceStaNo(wrkMast.getSourceStaNo()); if (wrkMast.getIoType() != 110 && wrkMast.getIoType() != 10) { List<WrkDetl> wrkDetls = wrkDetlService.findByWorkNo(wrkMast.getWrkNo()); wrkDetls.forEach(wrkDetl -> { Double total = 0.0; EntityWrapper<LocDetl> wrapper = new EntityWrapper<>(); LocDetl locDetl = locDetlService.selectOne(wrapper.eq("zpallet", wrkDetl.getZpallet()).eq("matnr", wrkDetl.getMatnr())); if (Cools.isEmpty(locDetl)) { total = wrkDetl.getAnfme(); } else { total = locDetl.getAnfme(); } if (wrkMast.getIoType() == 101 || wrkMast.getIoType() == 1) { ledCommand.getMatDtos().add(new MatDto(wrkDetl.getMatnr(), wrkDetl.getMaktx(), wrkDetl.getBatch(), wrkDetl.getSpecs(), wrkDetl.getManu(), wrkDetl.getMemo(), wrkDetl.getAnfme(), total)); } if (wrkMast.getIoType() == 103 && (null == wrkDetl.getInspect() || 0 == wrkDetl.getInspect())) { ledCommand.getMatDtos().add(new MatDto(wrkDetl.getMatnr(), wrkDetl.getMaktx(), wrkDetl.getBatch(), wrkDetl.getSpecs(), wrkDetl.getManu(), wrkDetl.getMemo(), wrkDetl.getAnfme(), total)); } if (wrkMast.getIoType() == 107 || wrkMast.getIoType() == 104) { ledCommand.getMatDtos().add(new MatDto(wrkDetl.getMatnr(), wrkDetl.getMaktx(), wrkDetl.getBatch(), wrkDetl.getSpecs(), wrkDetl.getManu(), wrkDetl.getMemo(), wrkDetl.getAnfme(), total)); } }); wrkDetls.forEach(wrkDetl -> ledCommand.getMatDtos().add(new MatDto(wrkDetl.getMatnr(), wrkDetl.getMaktx(), wrkDetl.getAnfme(),wrkDetl.getSpecs()))); } commands.add(ledCommand); } if (Cools.isEmpty(wrkMasts)) { continue; } Set<Integer> workNos = wrkMasts.stream().map(WrkMast::getWrkNo).collect(Collectors.toSet()); // 获取LED线程 @@ -1522,11 +1457,32 @@ if (CollectionUtils.equals(ledThread.getWorkNos(), workNos)) { continue; } // 命令下发 ------------------------------------------------------------------------------- // if (!commands.isEmpty()) { // if (led.getId() < 7) { // if (!MessageQueue.offer(SlaveType.Led, led.getId(), new Task(3, commands))) { // News.error(""+mark+" - 2"+" - {}号LED命令下发失败!!![ip:{}] [port:{}]", led.getId(), led.getIp(), led.getPort()); // continue; // } else { // ledThread.setLedMk(false); // } // } else { // if (!MessageQueue.offer(SlaveType.Led, led.getId(), new Task(1, commands))) { // News.error(""+mark+" - 3"+" - {}号LED命令下发失败!!![ip:{}] [port:{}]", led.getId(), led.getIp(), led.getPort()); // continue; // } else { // ledThread.setLedMk(false); // } // } // // } // 命令下发 ------------------------------------------------------------------------------- if (!commands.isEmpty()) { if (!MessageQueue.offer(SlaveType.Led, led.getId(), new Task(1, commands))) { News.error("{}号LED显示内容命令下发失败!!![ip:{}] [port:{}]", led.getId(), led.getIp(), led.getPort()); if (!MessageQueue.offer(SlaveType.Led, led.getId(), new Task(3, commands))) { News.error("{}号LED命令下发失败!!![ip:{}] [port:{}]", led.getId(), led.getIp(), led.getPort()); continue; }else { ledThread.setLedMk(false); } } @@ -1536,6 +1492,7 @@ wrkMast.setOveMk("Y"); wrkMast.setModiTime(new Date()); if (wrkMastMapper.updateById(wrkMast) == 0) { log.error(""+mark+" - 4"+" - 更新工作档失败"); throw new CoolException("更新工作档失败"); } } @@ -1549,6 +1506,7 @@ } } log.info(""+mark+" - 0"+" - 出库 ===>> 工作档信息写入led显示器执行完成"); } /** @@ -1958,38 +1916,6 @@ } } /** * 入出库模式切换函数 */ public void ioConvert() { try { // 根据输送线plc遍历 for (DevpSlave devp : slaveProperties.getDevp()) { SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId()); WrkMast pakout = wrkMastMapper.selectWorkingPakout(); if (pakout != null) { if (devpThread.ioMode != IoModeType.PAKOUT_MODE) { // 出库切换中 devpThread.ioMode = IoModeType.PAKOUT_BOOTING; WrkMast pakin = wrkMastMapper.selectWorkingPakin(); if (pakin == null) { // 出库模式 devpThread.ioMode = IoModeType.PAKOUT_MODE; } } } else { // 入库模式 devpThread.ioMode = IoModeType.PAKIN_MODE; } } } catch (Exception e) { e.printStackTrace(); } } public void outOfDevp() { List<WrkMast> wrkMasts = wrkMastMapper.selectPick(); for (WrkMast wrkMast : wrkMasts) { @@ -2076,232 +2002,6 @@ } } /** * 根据PLC按钮测试、完成、暂停信号,更新testMast表中status值,交由WMS系统处理 */ @Transactional public void packTest() { try { // 根据输送线plc遍历 for (DevpSlave devp : slaveProperties.getDevp()) { SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId()); if (null != devpThread) { for (int i = 0; i < 48; i++) { int olsStatus = 0;//testMast表原来status数据状态 int newStatus = 0;//testMast表待修改的status数据状态 short newSingle = 0; //PLC地址待修改的新值 switch (devpThread.startSignal[i][0]) {//根据信号查找testMast表中对应状态条件,olsStatus,newStatus根据实际流程调整 case 0://初始状态,入库 olsStatus = 1;//待测 newStatus = 1;//待测 newSingle = 1;//库存有资料,寄存器地址,0===>>1 break; case 2://启动复核信号 olsStatus = 1;//待测 newStatus = 2;//复核中 newSingle = 3;//测试复核,寄存器地址,2===>>3 break; case 3://测试完成 olsStatus = 4;//测试完成 newStatus = 4;//测试完成 newSingle = 4;//(NG:4\OK:41)测试完成,寄存器地址,3===>>4\41 break; case 5://NG测试信号 case 6://完成测试信号 case 22://完成测试信号 olsStatus = 4;//测试完成 newStatus = 5;//已移库 newSingle = 0;//启动移库,寄存器地址清零,5/6===>>0 break; case 7://暂停信号 olsStatus = 99;//plc给出暂停信号 newStatus = 0;//WCS收到暂停信号后,更新testMast newSingle = 8;//暂停测试,寄存器地址,7===>>8 break; case 9://紧急出库确认充电线已经拔出 olsStatus = 99;//plc给出暂停信号 newStatus = 0;//WCS收到暂停信号后,更新testMast newSingle = 8;//暂停测试,寄存器地址,9===>>8 break; case 10://解除暂停信号 olsStatus = 0;//plc给出暂停信号 newStatus = 1;//WCS收到暂停信号后,更新testMast newSingle = 0;//暂停测试,寄存器地址,10===>>0/11 break; case 12://紧急出库确认充电线已经拔出 newSingle = 11;//暂停测试,寄存器地址,12===>>11 break; case 13://入库前判断充电线是否放好 newSingle = 14;//禁用库位,寄存器地址,13===>>14 break; case 15://充电线放好 newSingle = 0;//复位,寄存器地址,12===>>0 break; default: log.info("读取通道" + (i + 1) + "测试库位按钮信号:为" + devpThread.startSignal[i][0]); continue; } TestMast testMast = testMastService.selectOne(new EntityWrapper<TestMast>() .eq("channel", (i + 1)).eq("status", olsStatus));//查找原来的状态 LocMast locMast = null; boolean sign = false; switch (devpThread.startSignal[i][0]) { case 0: if (!Cools.isEmpty(testMast)) { locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("channel", (i + 1))); if (!Cools.isEmpty(locMast) && locMast.getLocSts().equals("F")) { sign = true; } } break; case 3: if (!Cools.isEmpty(testMast)) { locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("channel", (i + 1))); if (!Cools.isEmpty(locMast) && locMast.getLocSts().equals("F")) { sign = true; if (locMast.getPackStatus() == 3) {//测试完成 newSingle = 41; } else if (locMast.getPackStatus() == 4) {//测试失败 newSingle = 4; } else { log.info("读取通道" + (i + 1) + "测试库位按钮信号:为" + devpThread.startSignal[i][0] + "通道库位pack状态信息异常" + locMast.getPackStatus()); sign = false; } } } break; case 5: case 6: if (!Cools.isEmpty(testMast)) { locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("channel", (i + 1))); if (!Cools.isEmpty(locMast) && locMast.getLocSts().equals("F")) { if (devpThread.startSignal[i][0] == 5 && locMast.getPackStatus() == 4) { sign = true; } else if (devpThread.startSignal[i][0] == 6 && locMast.getPackStatus() == 3) { sign = true; } else { log.error("测试完成移库时按下完成按钮与测试结果不一致===>>[channel:{}", i + 1); } } else { log.error("测试完成移库时未查询到测试档案===>>[channel:{}", i + 1); } } break; case 2: if (!Cools.isEmpty(testMast)) { testMast.setStatus(newStatus); testMast.setModiTime(new Date()); if (!testMastService.update(testMast, new EntityWrapper<TestMast>().eq("channel", (i + 1)).eq("barcode", testMast.getBarcode()))) { throw new CoolException("更新产品测试状态失败"); } else { sign = true; } } else { log.error("启动测试时未查询到测试档案===>>[channel:{}", i + 1); } break; case 7: SearchLocParam param = new SearchLocParam(); param.setBarcode(i + 1 + ""); String response = new HttpHandler.Builder() .setUri(wmsUrl) .setPath("/mobile/test/suspend/auth") .setJson(JSON.toJSONString(param)) .build() .doPost(); JSONObject jsonObject = JSON.parseObject(response); if (jsonObject.getInteger("code").equals(200)) { testMast = testMastService.selectOne(new EntityWrapper<TestMast>().eq("channel", (i + 1))); testMast.setStatus(newStatus); testMast.setModiTime(new Date()); if (!testMastService.update(testMast, new EntityWrapper<TestMast>().eq("channel", (i + 1)).eq("barcode", testMast.getBarcode()))) { log.error("更新产品测试状态失败"); } sign = true; } else { log.error("请求接口失败!!!url:{};request:{};response:{}", wmsUrl + "/mobile/test/suspend/auth", JSON.toJSONString(param), response); } break; case 9: case 12: locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("channel", (i + 1))); if (!Cools.isEmpty(locMast) && locMast.getLocSts().equals("F") || locMast.getLocSts().equals("D")) { locMast.setPackStatus(8); //8.紧急出库 if (locMastService.update(locMast, new EntityWrapper<LocMast>().eq("channel", (i + 1)))) { log.info("库位:{},紧急出库!", locMast.getLocNo()); } } else { log.error("库位不是在库状态,无需紧急出库!"); } sign = true; break; case 10: if (!Cools.isEmpty(testMast)) { locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("channel", (i + 1))); if (!Cools.isEmpty(locMast) && locMast.getLocSts().equals("F")) { if (locMast.getFireStatus().equals(1)) { newSingle = 11; } else { testMast.setStatus(newStatus); testMast.setModiTime(new Date()); if (!testMastService.update(testMast, new EntityWrapper<TestMast>().eq("channel", (i + 1)).eq("barcode", testMast.getBarcode()))) { throw new CoolException("更新产品测试状态失败"); } else { sign = true; } } } } sign = true; break; case 13: locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("channel", (i + 1))); if (locMast.getLocSts().equals("O")) { locMast.setLocSts("X"); locMastService.update(locMast, new EntityWrapper<LocMast>().eq("channel", (i + 1))); } sign = true; break; case 15: locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("channel", (i + 1))); if (locMast.getLocSts().equals("X")) { locMast.setLocSts("O"); locMastService.update(locMast, new EntityWrapper<LocMast>().eq("channel", (i + 1))); } sign = true; break; default: log.info("读取通道" + (i + 1) + "测试库位按钮信号:为" + devpThread.startSignal[i][0]); continue; } if (sign) { boolean result = messageQueueOffer(i, newSingle, SlaveType.Devp, devp.getId()); if (!result) { log.error("更新测试信号失败===>>[channel:{},locNo:{},barcode:{}]", i + 1, testMast.getLocNo(), testMast.getBarcode()); } else { devpThread.startSignal[i][0] = newSingle; } } try { locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("channel", (i + 1))); if (devpThread.startSignal[i][1] != locMast.getFireStatus()) { messageQueueOffer2(i + 1, (short) ((int) locMast.getFireStatus()), SlaveType.Devp, devp.getId()); } } catch (Exception e) { log.error("火警 ===>> 给输送线发送警报失败,通道号:", i + 1); } } } } } catch (Exception e) { log.error("启动测试 ===>> 启动测试失败", e); e.printStackTrace(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } } public boolean messageQueueOffer(int i, short newSingle, SlaveType devp, Integer id) { //复位PLC信号,借用输送站点实体类 @@ -2320,216 +2020,73 @@ } /** * 将火警报警信号写入到堆垛机PLC中 */ @Transactional public void fierCrn() { try { for (CrnSlave crn : slaveProperties.getCrn()) { if (crn.getId() != 1) { continue; } // 获取堆垛机信息 CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId()); CrnProtocol crnProtocol = crnThread.getCrnProtocol(); LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("fire_status", 1)); if (!Cools.isEmpty(locMast)) { //报警信号写入1 if (!MessageQueue.offer(SlaveType.Crn, 1, new Task(4, 1))) { News.error("火警 ===>> 给堆垛机发送报警信号失败"); } News.error("火警!!!!!!! ===>> 给堆垛机发送报警信号成功"); } else { //报警信号没有后,复位地址 if (!MessageQueue.offer(SlaveType.Crn, 1, new Task(4, 0))) { News.error("火警 ===>> 给堆垛机清零复位报警信号失败"); } } } } catch (Exception e) { News.error("火警 ===>> 给堆垛机发送警报失败", e); e.printStackTrace(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } } /** * 103站点有物下发pack码 */ @Transactional public void packDevp() { try { // 根据输送线plc遍历 for (DevpSlave devp : slaveProperties.getDevp()) { BasDevp basDevp = basDevpService.selectOne(new EntityWrapper<BasDevp>().eq("dev_no", 103)); if (Cools.isEmpty(basDevp)) { News.error("103站点查询失败-MainServiceImpl.java-2255行"); } if (basDevp.getAutoing().equals("Y") && basDevp.getWrkNo() > 0 && basDevp.getLoading().equals("Y")) { WrkDetl wrkDetl = wrkDetlService.devpPackNo(basDevp.getWrkNo()); if (Cools.isEmpty(wrkDetl)) { News.error("103站点查询失败-MainServiceImpl.java-2255行"); } MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(4, wrkDetl.getMatnr())); } } } catch (Exception e) { News.error("103 ===>> 给输送线发送Pack码失败", e); e.printStackTrace(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } } /** * 根据PLC按钮测试、完成、暂停信号,更新testMast表中status值,交由WMS系统处理 * 更新PLC库位状态、更新库位启动状态 */ @Transactional public void packTest1() { try { // 根据输送线plc遍历 for (DevpSlave devp : slaveProperties.getDevp()) { log.info("2363行程序开始运行"); SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId()); if (null != devpThread) { for (int i = 0; i < 48; i++) { // log.info("2367行程序开始运行,第"+i+"次"); boolean fig = false; if(null != devpThread){ //devpThread.startSignal[i][0] //0:空闲,1:待测,2:测试中;3.测试完成;4.测试失败; //locMast.setPackStatus // "产品状态{0:空闲,1:待测,2:测试中;3.测试完成;4.测试失败;}" //testMast.setStatus //"状态 0: 无货 1: 等待测试 2:测试中 3.测试完成;4.测试失败; " for (int i = 0; i < 24; i++){ //查询在库和预约出库 LocMast locMast = locMastService.selectztgx("F", "R", i); if (!Cools.isEmpty(locMast)) { // log.info("2372行程序开始运行,查询测试档"); TestMast testMast = testMastService.selectOne(new EntityWrapper<TestMast>() .eq("loc_no", locMast.getLocNo()) .eq("user_id", locMast.getBarcode())); if (Cools.isEmpty(testMast)) { LocMast locMast=locMastService.selectOne(new EntityWrapper<LocMast>().eq("channel",i+1)); if(!Cools.isEmpty(locMast)){ if (locMast.getLocSts().equals("F")){ TestMast testMast=testMastService.selectOne(new EntityWrapper<TestMast>() .eq("loc_no",locMast.getLocNo()) .eq("user_id",locMast.getBarcode())); if(Cools.isEmpty(testMast)){ // log.info("2377行程序开始运行,测试档为空,跳过"); continue; } // log.info("2380行程序开始运行,测试档不为空,下一步"); //devpThread.startSignal[i][0] //0:空,1:启动中,2:工作中,3:自动暂停,4:正常完成(OK),5:异常停止(NG),6:在线,7:离线,8:空闲 //locMast.setPackStatus // "产品状态{0:无,1:待测,2:测试中;3.测试完成;4.测试失败;5.静置中;6:静置完成;7:暂停测试;8:紧急出库;9:在线;10:离线;11:空闲;}" //testMast.setStatus //"状态 0: 待申请 1: 申请中 2: 已复核 3:测试中 4:完成 5:移库 6:火警" if (devpThread.startSignal[i][0] == 8) { News.info("2390行程序开始运行,修改测试档状态为 1、申请中,开始修改前:" + JSON.toJSONString(testMast)); testMast.setStatus(1); locMast.setPackStatus(1); testMast.setModiTime(new Date()); log.info("2394行程序开始运行,修改测试档状态为 1、申请中,修改数据后、未更新" + JSON.toJSONString(testMast)); } else if (devpThread.startSignal[i][0] == 2 && locMast.getPackStatus() != 2) { News.info("2396行程序开始运行,修改测试档状态为 3、测试中,开始修改前:" + JSON.toJSONString(testMast)); testMast.setStatus(3); locMast.setPackStatus(2); testMast.setModiTime(new Date()); log.info("2400,修改测试档状态为 3、测试中,修改数据后、未更新" + JSON.toJSONString(testMast)); //NG转OK需要还原源库位和目标库位状态,OK转NG 删除任务档 WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>() .eq("source_loc_no", locMast.getLocNo()) .eq("wrk_sts", 11)); News.info("2405,查询状态为生成出库id的测试完成(NG或OK)任务档," + JSON.toJSONString(wrkMast)); if (!Cools.isEmpty(wrkMast)) { if (wrkMast.getWrkSts() == 11) { if (wrkMast.getIoType() == 11) { log.info("2409,删除任务档为移库的," + JSON.toJSONString(wrkMast)); LocMast locMast1 = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", wrkMast.getLocNo())); locMast1.setLocSts("O"); locMastService.update(locMast1, new EntityWrapper<LocMast>().eq("loc_no", wrkMast.getLocNo())); } wrkMastMapper.deleteById(wrkMast); log.info("2415,删除工作档" + JSON.toJSONString(wrkMast) + JSON.toJSONString(locMast)); locMast.setLocSts("F"); log.info("2417,删除工作档" + JSON.toJSONString(wrkMast) + JSON.toJSONString(locMast)); wrkDetlService.delete(new EntityWrapper<WrkDetl>().eq("wrk_no", wrkMast.getWrkNo())); log.info("2419,删除工作明细" + wrkMast.getWrkNo()); if (!locMastService.update(locMast, new EntityWrapper<LocMast>() .eq("channel", i + 1))) { log.error("2422修改测试库位状态失败" + locMast.getLocNo() + JSON.toJSONString(locMast)); } else { log.error("2424修改测试库位状态成功" + locMast.getLocNo() + JSON.toJSONString(locMast)); fig = true; } } } } else if (devpThread.startSignal[i][0] == 3) { locMast.setPackStatus(7); testMast.setModiTime(new Date()); } else if (devpThread.startSignal[i][0] == 4 && testMast.getStatus() != 4 && locMast.getFireStatus() != 1 && testMast.getStatus() != 6) { locMast.setPackStatus(3); testMast.setStatus(4); testMast.setModiTime(new Date()); testMastService.insertPackQualified(true, new Date(), testMast.getBarcode()); } else if (devpThread.startSignal[i][0] == 5 && testMast.getStatus() != 4 && locMast.getFireStatus() != 1 && testMast.getStatus() != 6) { locMast.setPackStatus(4); testMast.setStatus(4); testMast.setModiTime(new Date()); testMastService.insertPackQualified(false, new Date(), testMast.getBarcode()); } // else if(devpThread.startSignal[i][0]==6||devpThread.startSignal[i][0]==7||devpThread.startSignal[i][0]==8){ // locMast.setPackStatus(devpThread.startSignal[i][0]+3); // } //通道启动按钮状态,1:可以启动出库或者移库,0:不能启动出库或者移库 locMast.setCtnKind(devpThread.startSignal[i][2]); if (devpThread.startSignal[i][2] == 1) { if (!locMastService.update(locMast, new EntityWrapper<LocMast>() .eq("loc_sts", "R") .eq("channel", i + 1))) { News.error("修改启动按钮状态,测试库位状态失败" + locMast.getLocNo(), locMast); } } else if (!locMast.getLocSts().equals("R")) { if (!fig) { if (!locMastService.update(locMast, new EntityWrapper<LocMast>() .eq("loc_sts", "F") .eq("channel", i + 1))) { News.error("修改测试库位状态失败" + locMast.getLocNo(), locMast); } } if (!testMastService.update(testMast, new EntityWrapper<TestMast>() .eq("loc_no", locMast.getLocNo()) .eq("user_id", locMast.getBarcode()))) { News.error("修改测试档状态失败" + locMast.getLocNo(), locMast); } } } } //当充放电库位为O空库位时 //库位状态改为8空闲 //给PLC写消防信号 for (int i = 0; i < 48; i++) { LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("channel", i + 1)); TestMast testMast = testMastService.selectOne(new EntityWrapper<TestMast>() .eq("loc_no", locMast.getLocNo()) .eq("user_id", locMast.getBarcode())); if ((locMast.getLocSts().equals("O") || locMast.getLocSts().equals("S")) && devpThread.startSignal[i][0] != 8) { Thread.sleep(1000); MessageQueue.offer(SlaveType.Devp, 1, new Task(6, locMast.getChannel() - 1)); } try { if (locMast.getFireStatus() != devpThread.startSignal[i][1]) { messageQueueOffer2(i, (short) ((int) locMast.getFireStatus()), SlaveType.Devp, devp.getId()); if (Cools.isEmpty(testMast)) { continue; } if (locMast.getFireStatus() == 1) { testMast.setStatus(6);//火警 if (!testMastService.update(testMast, new EntityWrapper<TestMast>() .eq("loc_no", locMast.getLocNo()) .eq("user_id", locMast.getBarcode()))) { News.error("修改测试档状态失败" + locMast.getLocNo(), locMast); HashMap<String,Short> hashMap=new HashMap<>(); if(devpThread.startSignal[i][0]!=locMast.getPackStatus()){ hashMap.put("locSts",locMast.getPackStatus().shortValue()); hashMap.put("channel",(short)(i*2)); MessageQueue.offer(SlaveType.Devp, 1, new Task(6,hashMap)); } //同步设备状态 if(locMast.getPackStatus()!=testMast.getStatus()){ testMast.setStatus(locMast.getPackStatus()); testMastService.updateById(testMast); } if(devpThread.startSignal[i][1]!=locMast.getCtnKind()){ locMast.setCtnKind(devpThread.startSignal[i][1]); locMastService.updateById(locMast); } }else if(locMast.getLocSts().equals("O")){ //当充放电库位为O空库位时 //库位状态改为0空闲 locMast=locMastService.selectztgx("O",i); if(!Cools.isEmpty(locMast)){ HashMap<String,Short> hashMap=new HashMap<>(); if(devpThread.startSignal[i][0]!=locMast.getPackStatus()){ hashMap.put("locSts",(short)0); hashMap.put("channel",(short)(i*2)); MessageQueue.offer(SlaveType.Devp, 1, new Task(6,hashMap)); locMast.setPackStatus(0); locMastService.updateById(locMast); } if(devpThread.startSignal[i][1]!=locMast.getChannel()){ locMast.setCtnKind(devpThread.startSignal[i][1]); locMastService.updateById(locMast); } } } } catch (Exception e) { News.error("火警 ===>> 给输送线发送警报失败,通道号:", i + 1); } } } } } catch (Exception e) { News.error("获得测试库位状态失败", e); src/main/java/com/zy/asrs/utils/Utils.java
@@ -4,9 +4,12 @@ import com.core.common.Cools; import com.zy.core.properties.SlaveProperties; import java.lang.reflect.Field; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Created by vincent on 2020/8/27 @@ -161,6 +164,20 @@ } public static Map<String, Object> objectToMap(Object obj) { Map<String, Object> map = new HashMap<>(); Field[] fields = obj.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); // 设置私有字段可访问 try { map.put(field.getName(), field.get(obj)); } catch (IllegalAccessException e) { e.printStackTrace(); } } return map; } public static void main(String[] args) { SlaveProperties slaveProperties = new SlaveProperties(); slaveProperties.setDoubleDeep(true); src/main/java/com/zy/core/MainProcess.java
@@ -59,15 +59,15 @@ // 堆垛机异常信息记录 mainService.recCrnErr(); // 入库 ===>> 空栈板初始化入库,叉车入库站放货 // mainService.storeEmptyPlt(); mainService.storeEmptyPlt(); // 出库 ===>> 工作档信息写入led显示器 mainService.ledExecute(); // mainService.ledExecute(1); // 其他 ===>> LED显示器复位,显示默认信息 mainService.ledReset(); // mainService.outOfDevp(); //启动、完成、暂停测试系统测试 // mainService.packTest1(); mainService.packTest1(); // //火警,给堆垛机发送火警警报 // mainService.fierCrn(); src/main/java/com/zy/core/thread/SiemensCrnThread.java
@@ -5,6 +5,7 @@ import HslCommunication.Profinet.Siemens.SiemensPLCS; import HslCommunication.Profinet.Siemens.SiemensS7Net; import com.alibaba.fastjson.JSON; import com.core.common.Cools; import com.core.common.DateUtils; import com.core.common.SpringUtils; import com.zy.asrs.entity.BasCrnOpt; @@ -39,6 +40,11 @@ private CrnProtocol crnProtocol; private boolean resetFlag = false; public Long sign = System.currentTimeMillis(); public boolean isRunning = true; /** * 堆垛机是否在回原点运动中标记 */ @@ -52,7 +58,7 @@ @SuppressWarnings("InfiniteLoopStatement") public void run() { this.connect(); while (true) { while (isRunning) { try { int step = 1; Task task = MessageQueue.poll(SlaveType.Crn, slave.getId()); @@ -86,10 +92,6 @@ command.setDestinationPosZ((short)0); // 目标库位层 write(command); break; case 4: Integer data = (Integer) task.getData(); siemensNet.Write("DB100.276", data.shortValue()); break; default: break; } @@ -97,7 +99,7 @@ } catch (Exception e) { // e.printStackTrace(); } sign = System.currentTimeMillis(); } } @@ -137,10 +139,10 @@ if(connect.IsSuccess){ result = true; OutputQueue.CRN.offer(MessageFormat.format( "【{0}】堆垛机plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot())); log.info("堆垛机plc连接成功 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()); News.info("SiemensCrn"+" - 1"+" - 堆垛机plc连接成功 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()); } else { OutputQueue.CRN.offer(MessageFormat.format("【{0}】堆垛机plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot())); log.error("堆垛机plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()); News.error("SiemensCrn"+" - 2"+" - 堆垛机plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()); initCrn(); } // siemensNet.ConnectClose(); @@ -152,10 +154,11 @@ */ private void readStatus(){ try { OperateResultExOne<byte[]> result = siemensNet.Read("DB101.0", (short) 65); OperateResultExOne<byte[]> result = siemensNet.Read("DB101.0", (short) 56); if (result.IsSuccess) { if (null == crnProtocol) { crnProtocol = new CrnProtocol(); crnProtocol.setCrnNo(slave.getId()); } crnProtocol.setMode(siemensNet.getByteTransform().TransInt16(result.Content, 0)); crnProtocol.setTaskNo(siemensNet.getByteTransform().TransInt16(result.Content, 2)); @@ -178,13 +181,11 @@ crnProtocol.setyDistance(siemensNet.getByteTransform().TransInt16(result.Content, 44)); crnProtocol.setxDuration(siemensNet.getByteTransform().TransInt16(result.Content, 48)); crnProtocol.setyDuration(siemensNet.getByteTransform().TransInt16(result.Content, 52)); crnProtocol.setBarcodeResult(siemensNet.getByteTransform().TransBool(result.Content, 56)); crnProtocol.setBarcode(siemensNet.getByteTransform().TransString(result.Content, 58,6,"UTF-8")); OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId())); // 复位信号 if (crnProtocol.getStatusType().equals(CrnStatusType.WAITING)) { if (!Cools.isEmpty(crnProtocol.getStatusType()) && crnProtocol.getStatusType().equals(CrnStatusType.WAITING)) { if (resetFlag) { if(crnProtocol.getTaskNo()==9999){ backHpFlag = false; @@ -204,19 +205,19 @@ basCrnp.setCrnNo(slave.getId()); basCrnp.setCrnSts((int)crnProtocol.getMode()); if (!basCrnpService.updateById(crnProtocol.toSqlModel(basCrnp))){ log.error("堆垛机plc数据库更新失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()); News.error("SiemensCrn"+" - 3"+" - 堆垛机plc数据库更新失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()); } } catch (Exception ignore){} } else { initCrn(); OutputQueue.CRN.offer(MessageFormat.format("【{0}】读取堆垛机plc状态信息失败1 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot())); log.error("读取堆垛机plc状态信息失败1 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()); OutputQueue.CRN.offer(MessageFormat.format("【{0}】读取堆垛机plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot())); News.error("SiemensCrn"+" - 4"+" - 读取堆垛机plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()); } } catch (Exception e) { log.error("fail", e); OutputQueue.CRN.offer(MessageFormat.format("【{0}】读取堆垛机plc状态信息失败2 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); log.error("读取堆垛机plc状态信息失败2 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); e.printStackTrace(); OutputQueue.CRN.offer(MessageFormat.format("【{0}】读取堆垛机plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); News.error("SiemensCrn"+" - 5"+" - 读取堆垛机plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); initCrn(); } } @@ -235,12 +236,12 @@ */ private boolean write(CrnCommand command) throws InterruptedException { if (null == command) { log.error("堆垛机写入命令为空"); News.error("SiemensCrn"+" - 6"+" - 堆垛机写入命令为空"); return false; } //convertRow(command); // convertRow(command); command.setCrnNo(slave.getId()); short[] array = new short[12]; short[] array = new short[10]; array[0] = command.getAckFinish(); array[1] = command.getTaskNo(); array[2] = command.getTaskMode(); @@ -250,15 +251,14 @@ array[6] = command.getDestinationPosX(); array[7] = command.getDestinationPosY(); array[8] = command.getDestinationPosZ(); array[9] = command.getSourceStaNo(); array[10] = command.getDestinationStaNo(); array[11] = command.getCommand(); // array[9] = command.getSourceStaNo(); // array[10] = command.getDestinationStaNo(); array[9] = command.getCommand(); OperateResult result = siemensNet.Write("DB100.0", array); if (command.getAckFinish() == 0){ OperateResult result2 = siemensNet.Write("DB100.20", command.getBarcode()); } if (command.getAckFinish() == 0) { short commandFinish = 1; Thread.sleep(100L); result = siemensNet.Write("DB100.18", commandFinish); } @@ -288,12 +288,12 @@ if (result != null && result.IsSuccess) { Thread.sleep(200); this.readStatus(); log.info("堆垛机命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command)); News.info("SiemensCrn"+" - 7"+" - 堆垛机命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command)); OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command))); return true; } else { OutputQueue.CRN.offer(MessageFormat.format("【{0}】写入堆垛机plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); log.error("写入堆垛机plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); News.error("SiemensCrn"+" - 8"+" - 写入堆垛机plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); return false; } } @@ -419,4 +419,9 @@ } // 提供一个方法来停止线程 public void requestStop() { isRunning = false; } } src/main/java/com/zy/core/thread/SiemensDevpThread.java
@@ -5,11 +5,14 @@ import HslCommunication.Profinet.Siemens.SiemensPLCS; import HslCommunication.Profinet.Siemens.SiemensS7Net; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.core.common.Cools; import com.core.common.DateUtils; import com.core.common.SpringUtils; import com.core.exception.CoolException; import com.zy.asrs.entity.BasDevp; import com.zy.asrs.service.BasDevpService; import com.zy.asrs.utils.Utils; import com.zy.core.DevpThread; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.OutputQueue; @@ -22,11 +25,9 @@ import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.lang.reflect.Field; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.*; import java.util.concurrent.ConcurrentHashMap; /** @@ -41,29 +42,43 @@ private SiemensS7Net siemensS7Net; private Map<Integer, StaProtocol> station = new ConcurrentHashMap<>(); private short heartBeatVal = 1; public static final ArrayList<Integer> staNos = new ArrayList<Integer>() {{ add(101); add(102); add(103); add(104); add(201); add(202); add(203); add(204); add(205); add(206); public static final ArrayList<Integer> staNos1 = new ArrayList<Integer>() {{ add(100);add(101);add(102);add(103);add(104);add(105);add(106); }}; private Integer count=0; public int[][] startSignal = new int[24][2]; /** * 条码数量 */ private int barcodeSize = 1; public IoModeType ioMode = IoModeType.NONE; public int[][] startSignal = new int[48][3]; /** * 入出库模式 * 0:未知 * 1:入库启动中 * 2.入库模式 * 3.出库启动中 (不能生成入库工作档) * 4.出库模式 */ // public IoModeType ioMode = IoModeType.NONE; public SiemensDevpThread(DevpSlave slave) { this.slave = slave; } private ArrayList<Integer> getStaNo() { switch (slave.getId()) { case 1: return staNos1; default: throw new CoolException("服务器异常"); } } @Override @@ -84,28 +99,14 @@ break; // 写数据 ID+目标站 case 2: write((StaProtocol) task.getData()); write((StaProtocol)task.getData()); break; // 写数据 103站点写入PACK码 // case 4: // write103((String)task.getData()); // break; // 火警信号 // case 5: // StaProtocol staProtocol2 = (StaProtocol)task.getData(); // siemensS7Net.Write("DB108.0" + staProtocol2.getSiteId(), staProtocol2.getStaNo()==1); // break; //测试库出库,库位状态改为8 // case 6: // String data = task.getData()+""; // Byte coun=8; // siemensS7Net.Write("DB38.0" + data, coun); // break; //复位测试信号 // case 3: // StaProtocol staProtocol = (StaProtocol) task.getData(); // siemensS7Net.Write("DB102.0" + staProtocol.getSiteId(), staProtocol.getStaNo()); // break; //修改测试状态 case 6: Map<String, Short> map = (Map<String, Short>) task.getData(); siemensS7Net.Write("DB102.0" + map.get("channel"),map.get("locSts")); break; default: break; } @@ -119,6 +120,37 @@ } } /** * 初始化站点状态 */ private void initSite() { count ++; ArrayList<Integer> staNos = getStaNo(); if(count > 10) { // 站点编号 for (Integer siteId : staNos) { StaProtocol staProtocol = station.get(siteId); if (null == staProtocol) { staProtocol = new StaProtocol(); staProtocol.setSiteId(siteId); station.put(siteId, staProtocol); } staProtocol.setWorkNo((short) 0); // ID staProtocol.setAutoing(false); // 自动 staProtocol.setLoading(false); // 有物 staProtocol.setInEnable(false); // 可入 staProtocol.setOutEnable(false); // 可出 staProtocol.setEmptyMk(false); // 空板信号 staProtocol.setStaNo((short) 0); // 目标站 if (!staProtocol.isPakMk() && !staProtocol.isLoading()) { staProtocol.setPakMk(true); } } count = 0; } } @Override public boolean connect() { boolean result = false; @@ -126,13 +158,14 @@ siemensS7Net.setRack(slave.getRack().byteValue()); siemensS7Net.setSlot(slave.getSlot().byteValue()); OperateResult connect = siemensS7Net.ConnectServer(); if (connect.IsSuccess) { if(connect.IsSuccess){ result = true; OutputQueue.DEVP.offer(MessageFormat.format("【{0}】输送线plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot())); OutputQueue.DEVP.offer(MessageFormat.format( "【{0}】输送线plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot())); log.info("输送线plc连接成功 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); } else { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】输送线plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot())); OutputQueue.DEVP.offer(MessageFormat.format( "【{0}】输送线plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot())); log.error("输送线plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); initSite(); } siemensS7Net.ConnectClose(); return result; @@ -142,10 +175,10 @@ * 读取状态 ====> 整块plc */ private void read() throws InterruptedException { // // 更新入出库模式 // updateIoMode(); ArrayList<Integer> staNos = getStaNo(); int staNoSize = staNos.size(); OperateResultExOne<byte[]> result = siemensS7Net.Read("DB100.0", (short) (staNoSize * 4)); OperateResultExOne<byte[]> result = siemensS7Net.Read("DB101.0", (short) (staNoSize*8)); if (result.IsSuccess) { for (int i = 0; i < staNoSize; i++) { Integer siteId = staNos.get(i); // 站点编号 @@ -155,32 +188,11 @@ staProtocol.setSiteId(siteId); station.put(siteId, staProtocol); } staProtocol.setWorkNo(siemensS7Net.getByteTransform().TransInt16(result.Content, i * 4)); // 工作号 staProtocol.setWorkNo((short)siemensS7Net.getByteTransform().TransInt32(result.Content, i*8)); // 工作号 staProtocol.setStaNo(siemensS7Net.getByteTransform().TransInt16(result.Content, i * 4 + 2)); // 目标站 } } // Thread.sleep(200); // OperateResultExOne<byte[]> result0 = siemensS7Net.Read("DB101.0", (short) 186); // if (result0.IsSuccess) { // for (int i = 0; i < 93; i++) { // Integer siteId = staNos.get(i); // 站点编号 // StaProtocol staProtocol = station.get(siteId); // if (null == staProtocol) { // staProtocol = new StaProtocol(); // staProtocol.setSiteId(siteId); // station.put(siteId, staProtocol); // } // staProtocol.setStaNo(siemensS7Net.getByteTransform().TransInt16(result0.Content, i*2)); // 目标站 // } // } Thread.sleep(200); OperateResultExOne<byte[]> result1 = siemensS7Net.Read("DB101.0", (short) (staNoSize * 2)); if (result1.IsSuccess) { for (int i = 0; i < staNoSize; i++) { Integer siteId = staNos.get(i); // 站点编号 boolean[] status = siemensS7Net.getByteTransform().TransBool(result1.Content, i * 2, 1); StaProtocol staProtocol = station.get(siteId); staProtocol.setStaNo(siemensS7Net.getByteTransform().TransInt16(result.Content, i*8 + 4)); // 目标站 boolean[] status = siemensS7Net.getByteTransform().TransBool(result.Content, i*8 + 6, 2); staProtocol.setAutoing(status[0]); // 自动 staProtocol.setLoading(status[1]); // 有物 staProtocol.setInEnable(status[2]); // 可入 @@ -196,61 +208,50 @@ } } Thread.sleep(200); OperateResultExOne<byte[]> result2 = siemensS7Net.Read("DB100.190", (short) 8); // OperateResultExOne<byte[]> result5 = siemensS7Net.Read("DB100.216",(short)(6)); if (result2.IsSuccess) { String barcode = siemensS7Net.getByteTransform().TransString(result2.Content, 0, 8, "UTF-8"); // String barcode=new String(result2.Content,i*12,12); BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, 1); if (!Cools.isEmpty(barcodeThread) && !barcodeThread.getBarcode().equals(barcode)) { barcodeThread.setBarcode(barcode); } //外形检测 OperateResultExOne<byte[]> resultErr1 = siemensS7Net.Read("DB101.702.0", (short) (barcodeSize*1)); StaProtocol staProtocol1 = station.get(101); if(resultErr1.IsSuccess){ boolean[] status1 = siemensS7Net.getByteTransform().TransBool(resultErr1.Content, 0, 1); staProtocol1.setFrontErr(status1[0]); staProtocol1.setBackErr(status1[1]); staProtocol1.setHighErr(status1[2]); staProtocol1.setLeftErr(status1[3]); staProtocol1.setRightErr(status1[4]); staProtocol1.setWeightErr(status1[5]); staProtocol1.setBarcodeErr(status1[6]); } // if (result5.IsSuccess) { // String barcode =siemensS7Net.getByteTransform().TransString(result5.Content,0,6, "UTF-8"); //// String barcode=new String(result2.Content,i*12,12); // BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, 2); // if(!Cools.isEmpty(barcodeThread) && !barcodeThread.getBarcode().equals(barcode)) { // barcodeThread.setBarcode(barcode); // } // } Thread.sleep(200); //测试柜状态获取 OperateResultExOne<byte[]> result3 = siemensS7Net.Read("DB38.0", (short) 48); //启动移库按钮 OperateResultExOne<byte[]> result6 = siemensS7Net.Read("DB102.0", (short) 96); //消防报警 OperateResultExOne<byte[]> result4 = siemensS7Net.Read("DB108.0", (short) 48); if (result3.IsSuccess) { for (int i = 0; i < 48; i++) { startSignal[i][0] = siemensS7Net.getByteTransform().TransByte(result3.Content, i);//测试柜状态 startSignal[i][1] = siemensS7Net.getByteTransform().TransBool(result4.Content, i) ? 1 : 0;//消防状态 startSignal[i][2] = siemensS7Net.getByteTransform().TransInt16(result6.Content, i * 2);//启动按钮状态 if(slave.getId()==1) { OperateResultExOne<byte[]> result2 = siemensS7Net.Read("DB101.602.0", (short) (barcodeSize * 8)); if (result2.IsSuccess) { for (int i = 0; i < barcodeSize; i++) { String barcode = siemensS7Net.getByteTransform().TransString(result2.Content, i * 8, 8, "UTF-8"); BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, i + 1); if (!Cools.isEmpty(barcodeThread) && !barcodeThread.getBarcode().equals(barcode)) { barcodeThread.setBarcode(barcode); } } } } // OperateResultExOne<Short> result2 = siemensS7Net.ReadInt16("DB200.0"); // if (result2.IsSuccess) { // this.ioMode = IoModeType.get(result2.Content); // } OperateResultExOne<byte[]> result202 = siemensS7Net.Read("DB101.806", (short) 8); if (result202.IsSuccess) { //出入库模式 boolean[] status = siemensS7Net.getByteTransform().TransBool(result202.Content, 0, 1); StaProtocol staProtocol = station.get(202); staProtocol.setFrontErr(status[0]); staProtocol.setBackErr(status[1]); staProtocol.setHighErr(status[2]); staProtocol.setLeftErr(status[3]); staProtocol.setRightErr(status[4]); staProtocol.setWeightErr(status[5]); staProtocol.setBarcodeErr(status[6]); //充放电库位状态读取 OperateResultExOne<byte[]> resultLocSts = siemensS7Net.Read("DB102.0", (short) 48); //充放电启动按钮读取 OperateResultExOne<byte[]> resultLocOpen = siemensS7Net.Read("DB103.0", (short) 48); if(resultLocSts.IsSuccess&&resultLocOpen.IsSuccess) { for(int i=0; i<24; i++){ startSignal[i][0] = siemensS7Net.getByteTransform().TransInt16(resultLocSts.Content, i*2);//测试柜状态 startSignal[i][1] = siemensS7Net.getByteTransform().TransInt16(resultLocOpen.Content, i*2);//启动按钮状态 } } if (result.IsSuccess && result1.IsSuccess) { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功", DateUtils.convert(new Date()), slave.getId())); if (result.IsSuccess) { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId())); // 根据实时信息更新数据库 try { @@ -271,27 +272,9 @@ } } else { initSite(); OutputQueue.DEVP.offer(MessageFormat.format("【{0}】读取输送线plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot())); // log.error("读取输送线plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()); } } /** * 写入 pack码 =====> 单站点写入 */ private void write103(String packNo) { try { OperateResult write = siemensS7Net.Write("DB109.0", packNo); if (!write.IsSuccess) { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(packNo))); log.error("写入输送线站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(packNo)); } else { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】 输送线命令下发 [id:{1}] >>>>> {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(packNo))); log.info("输送线命令下发 [id:{}] >>>>> 命令下发: {}", slave.getId(), JSON.toJSON(packNo)); } } catch (Exception e) { log.error("103站点写入数据失败,输送线线程write103"); } } @@ -302,90 +285,34 @@ if (null == staProtocol) { return; } int staNoSize = staNos.size(); ArrayList<Integer> staNos = getStaNo(); int index = staNos.indexOf(staProtocol.getSiteId()); short[] array = new short[2]; array[0] = staProtocol.getWorkNo(); array[1] = staProtocol.getStaNo(); OperateResult writeResult1 = siemensS7Net.Write("DB100." + index*6, staProtocol.getWorkNo().intValue()); // 工作号 OperateResult writeResult2 = siemensS7Net.Write("DB100." + (index*6+4), staProtocol.getStaNo()); // 目标站 //任务ID下发次数 int idCount = 0; boolean idFlag = false; OperateResult write; while (idCount < 5) { // OperateResult write = siemensS7Net.Write("DB100.0" + index*4, staProtocol.getWorkNo()); // 工作号 // Thread.sleep(500); // OperateResult write1 = siemensS7Net.Write("DB100.2" + index*4+2, staProtocol.getStaNo()); // 目标站 write = siemensS7Net.Write("DB100." + index * 4, array); // 写 if (write.IsSuccess) { Thread.sleep(200); OperateResultExOne<byte[]> readId = siemensS7Net.Read("DB100." + index * 4, (short) (staNoSize * 2)); if (readId.IsSuccess) { if (staProtocol.getWorkNo() != 0 && staProtocol.getWorkNo() != 9999) { if (!staProtocol.isInEnable() && (staProtocol.getSiteId() == 201 || staProtocol.getSiteId() == 206)) { break; } } short workNo = siemensS7Net.getByteTransform().TransInt16(readId.Content, 0); if (staProtocol.getWorkNo().equals(workNo)) { //工作号写入成功 idFlag = true; break; } else {//返回结果是成功了,但是真实值不相同 idCount++; OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线工作号后返回成功,但是读取工作号值不一致。输送线plc编号={1},站点数据={2},写入次数={3}", slave.getId(), JSON.toJSON(staProtocol), idCount)); log.error("写入输送线工作号后返回成功,但是读取工作号值不一致。输送线plc编号={},{},写入次数={}", slave.getId(), JSON.toJSON(staProtocol), idCount); } } else { idCount++; OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线工作号后读取工作号失败。输送线plc编号={1},站点数据={2},写入次数={3}", slave.getId(), JSON.toJSON(staProtocol), idCount)); log.error("写入输送线工作号后读取工作号失败。输送线plc编号={},站点数据={},写入次数={}", slave.getId(), JSON.toJSON(staProtocol), idCount); } } else { idCount++; OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线工作号失败。输送线plc编号={1},站点数据={2},写入次数={3}", slave.getId(), JSON.toJSON(staProtocol), idCount)); log.error("写入输送线工作号失败。输送线plc编号={},站点数据={},写入次数={}", slave.getId(), JSON.toJSON(staProtocol), idCount); } Thread.sleep(200); } //写ID尝试了5次还是失败了 if (!idFlag) { if (!writeResult1.IsSuccess&&!writeResult2.IsSuccess) { staProtocol = station.get(staProtocol.getSiteId()); if (staProtocol.getWorkNo() == 9999 && staProtocol.getStaNo() == 0) { if (staProtocol.getWorkNo() == 0 && staProtocol.getStaNo() ==0) { staProtocol.setPakMk(true); } OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线工作号尝试5次失败。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(staProtocol))); log.error("写入输送线工作号尝试5次失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(staProtocol)); //重新添加数据到任务队列 boolean result = MessageQueue.offer(SlaveType.Devp, slave.getId(), new Task(2, staProtocol)); read();//读取1次设备状态 return; } // OperateResult write = siemensS7Net.Write("DB100." + index*2, staProtocol.getWorkNo()); // 工作号 // Thread.sleep(500); // OperateResult write1 = siemensS7Net.Write("DB101." + index*2, staProtocol.getStaNo()); // 目标站 OutputQueue.DEVP.offer(MessageFormat.format("【{0}】 输送线命令下发成功 [id:{1}] >>>>> {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(staProtocol))); log.info("输送线命令下发 [id:{}] >>>>> 命令下发成功: {}", slave.getId(), JSON.toJSON(staProtocol)); } // 更新入出库模式 private void updateIoMode() throws InterruptedException { if (this.ioMode != IoModeType.NONE) { if (!siemensS7Net.Write("DB200", this.ioMode.id).IsSuccess) { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线1F入出库模式失败。输送线plc编号={1}", slave.getId())); log.error("写入输送线1F入出库模式失败。输送线plc编号={}", slave.getId()); } OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(staProtocol))); log.error("写入输送线站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(staProtocol)); } else { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】 输送线命令下发 [id:{1}] >>>>> {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(staProtocol))); log.info("输送线命令下发 [id:{}] >>>>> 命令下发: {}", slave.getId(), JSON.toJSON(staProtocol)); } } /** * 心跳 */ private void heartbeat() { private void heartbeat(){ if (heartBeatVal == 1) { heartBeatVal = 2; } else { @@ -414,16 +341,16 @@ } public static void main(String[] args) { System.out.println(staNos.indexOf(129)); System.out.println(staNos.size()); for (int i = 0; i < staNos.size(); i++) { System.out.println(staNos1.indexOf(129)); System.out.println(staNos1.size()); for (int i = 0; i< staNos1.size(); i++) { // System.out.println(i*2); // System.out.println(i*2 + 200); // System.out.println(i); } int index = staNos.indexOf(128); System.out.println(index * 2); System.out.println(index * 2 + 200); int index = staNos1.indexOf(128); System.out.println(index*2); System.out.println(index*2 + 200); } // public static void main(String[] args) throws Exception { src/main/resources/application.yml
@@ -35,20 +35,20 @@ enable: false wms: url: 10.12.55.200:8080/fnwms url: 127.0.0.1:8081/tlfwms # 下位机配置 wcs-slave: # 双深 doubleDeep: false # 双深库位排号 doubleLocs: doubleLocs: 3 # 一个堆垛机负责的货架排数 groupCount: 2 groupCount: 3 # 堆垛机1 crn[0]: id: 1 ip: 10.12.55.70 ip: 178.18.1.150 port: 8888 rack: 0 slot: 0 @@ -58,29 +58,21 @@ # 堆垛机入库站点 crnInStn[0]: devpPlcId: ${wcs-slave.devp[0].id} staNo: 202 row: 1 bay: 0 staNo: 100 row: 2 bay: 1 lev: 1 # 堆垛机出库站点 crnOutStn[0]: devpPlcId: ${wcs-slave.devp[0].id} staNo: 1000 staNo: 106 row: 1 bay: 25 bay: 1 lev: 1 # 堆垛机出库站点 crnOutStn[1]: devpPlcId: ${wcs-slave.devp[0].id} staNo: 203 row: 2 bay: 0 lev: 1 # 输送线 devp[0]: id: 1 ip: 10.12.55.90 ip: 178.18.1.160 port: 102 rack: 0 slot: 0 @@ -88,36 +80,22 @@ inSta[0]: staNo: 101 barcode: ${wcs-slave.barcode[0].id} backSta: 100 backSta: 102 led: ${wcs-slave.led[0].id} # 空板入库口1 emptyInSta[0]: staNo: 201 # 空板入库口2 emptyInSta[1]: staNo: 206 staNo: 101 # 出库口1 outSta[0]: staNo: 204 staNo: 104 # 出库口2 outSta[1]: staNo: 103 # 出库口3 outSta[2]: staNo: 205 # 出库口4 outSta[3]: staNo: 1000 staNo: 102 # 条码扫描仪1 barcode[0]: id: 1 ip: 172.28.15.235 port: 51236 # # 条码扫描仪2 # barcode[1]: # id: 2 # ip: 172.28.15.235 # port: 51236 # LED1 led[0]: id: 1 @@ -131,7 +109,7 @@ ip: 10.10.10.60 port: 5005 devpPlcId: ${wcs-slave.devp[0].id} staArr: 110 staArr: 104 # # #socket # socket[0]: src/main/resources/mapper/LocMastMapper.xml
@@ -64,7 +64,7 @@ </select> <select id="selectztgx" resultMap="BaseResultMap"> select top 1 * from asr_loc_mast where loc_sts in (#{sts1},#{sts2}) and channel=#{count}+1 select top 1 * from asr_loc_mast where loc_sts in (#{sts1}) and channel=#{count}+1 </select> </mapper> src/main/resources/mapper/WrkDetlMapper.xml
@@ -48,7 +48,7 @@ </resultMap> <select id="findByWorkNo" resultMap="BaseResultMap"> select wrk_no, mat_no, mat_name, qty from asr_wrk_detl where 1=1 and wrk_no = #{workNo} select wrk_no, mat_name, qty from asr_wrk_detl where 1=1 and wrk_no = #{workNo} </select> <select id="devpPackNo" resultMap="BaseResultMap"> select top 1 * from asr_wrk_detl_log where 1=1 and wrk_no = #{workNo} order by io_time desc