src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -1,24 +1,33 @@ package com.zy.asrs.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.Cools; import com.zy.asrs.domain.enums.NotifyMsgType; import com.zy.asrs.entity.*; import com.zy.asrs.service.*; import com.zy.asrs.utils.NotifyUtils; import com.zy.asrs.utils.Utils; import com.zy.common.model.*; import com.zy.common.model.MapNode; import com.zy.common.model.NavigateNode; import com.zy.common.model.SearchLocParam; import com.zy.common.model.StartupDto; import com.zy.common.model.enums.NavigationMapType; import com.zy.common.service.CommonService; import com.zy.common.utils.*; import com.zy.core.News; import com.zy.core.action.LiftAction; import com.zy.core.action.ShuttleAction; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.SlaveConnection; import com.zy.core.dispatcher.ShuttleDispatchUtils; import com.zy.core.enums.*; import com.zy.core.model.*; import com.zy.core.model.command.*; import com.zy.core.model.command.LiftAssignCommand; import com.zy.core.model.command.LiftCommand; import com.zy.core.model.command.ShuttleAssignCommand; import com.zy.core.model.command.ShuttleCommand; import com.zy.core.model.protocol.*; import com.zy.core.properties.SlaveProperties; import com.zy.core.thread.*; @@ -28,7 +37,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.*; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; /** * 立体仓库WCS系统主流程业务 @@ -78,6 +90,250 @@ private BasLiftOptService basLiftOptService; @Autowired private LiftAction liftAction; //入库站点 public static final ArrayList<Integer> inSta = new ArrayList<Integer>() {{ add(1012); add(1014); add(1022); add(1025); add(1032); }}; //出库站点 public static final ArrayList<Integer> outSta = new ArrayList<Integer>() {{ add(1012); add(1014); add(1022); add(1025); add(1032); }}; private boolean isInEnable(DevpThread devpThread, Integer staNo) { if (staNo == null) { return false; } // 获取入库站信息 switch (staNo) { case 1011: case 1012: devpThread.getStation().get(1012).isInEnable(); break; case 1021: case 1022: case 1023: devpThread.getStation().get(1022).isInEnable(); break; case 1031: case 1032: devpThread.getStation().get(1032).isInEnable(); break; case 1025: case 1026: devpThread.getStation().get(1025).isInEnable(); break; case 1013: case 1014: case 1015: devpThread.getStation().get(1014).isInEnable(); break; } return false; } private boolean isOutEnable(DevpThread devpThread, Integer staNo) { if (staNo == null) { return false; } // 获取入库站信息 switch (staNo) { case 1011: case 1012: devpThread.getStation().get(1012).isOutEnable(); break; case 1021: case 1022: case 1023: devpThread.getStation().get(1022).isOutEnable(); break; case 1031: case 1032: devpThread.getStation().get(1032).isOutEnable(); break; case 1025: case 1026: devpThread.getStation().get(1025).isOutEnable(); break; case 1013: case 1014: case 1015: devpThread.getStation().get(1014).isOutEnable(); break; } return false; } /** * 组托 * 入库站,根据条码扫描生成入库工作档,工作状态 2 */ public synchronized void generateInboundWrk() { try { DevpSlave devpSlave = slaveProperties.getDevpSlave().get(0); // 遍历入库口 for (DevpSlave.Sta inSta : devpSlave.getInSta()) { // 获取入库站信息 DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devpSlave.getId()); StaProtocol staProtocol = devpThread.getStation().get(inSta.getStaNo()); if (staProtocol == null) { continue; } else { staProtocol = staProtocol.clone(); } Short workNo = staProtocol.getWorkNo(); // 尺寸检测异常 boolean back = false; String errMsg = "异常:"; if (staProtocol.isFrontErr()) { errMsg = errMsg + "前超限;"; back = true; } if (staProtocol.isBackErr()) { errMsg = errMsg + "后超限"; back = true; } if (staProtocol.isHighErr()) { errMsg = errMsg + "高超限"; back = true; } if (staProtocol.isLeftErr()) { errMsg = errMsg + "左超限"; back = true; } if (staProtocol.isRightErr()) { errMsg = errMsg + "右超限"; back = true; } if (staProtocol.isWeightErr()) { errMsg = errMsg + "超重"; back = true; } if (staProtocol.isBarcodeErr()) { errMsg = errMsg + "扫码失败"; back = true; } // 退回 if (back) { // led 异常显示 LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed()); if (ledThread != null) { ledThread.error(errMsg); } continue; } // 判断是否满足入库条件 if (staProtocol.isAutoing() && staProtocol.isLoading() && isInEnable(devpThread, inSta.getStaNo()) && !staProtocol.isEmptyMk() && (workNo == 0 || (workNo >= 9990 && workNo <= 9999)) && staProtocol.isPakMk() ) { String barcode = staProtocol.getBarcode(); if (!Cools.isEmpty(barcode)) { News.info("条码扫描器检测条码信息:{}", barcode); } // 判断重复工作档 WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>() .eq("source_sta_no", inSta.getStaNo()) .eq("wrk_sts", WrkStsType.NEW_INBOUND) .eq("barcode", barcode)); if (wrkMast != null) { News.error("工作档已存在,工作号={}", wrkMast.getWrkNo()); if (staProtocol.getWorkNo().intValue() != wrkMast.getWrkNo()) { MessageQueue.offer(SlaveType.Devp, devpSlave.getId(), new Task(2, staProtocol)); devpThread.setPakMk(staProtocol.getSiteId(), false); News.info("输送线入库命令下发,任务数据={}", JSON.toJSON(wrkMast)); } continue; } try { String wmsUrl = "127.0.0.1:8080/fyxcwms"; SearchLocParam param = new SearchLocParam(); param.setBarcode(barcode); param.setIoType(1); param.setSourceStaNo(inSta.getStaNo()); param.setLocType1(staProtocol.getLocType1().shortValue()); String response = new HttpHandler.Builder() .setUri(wmsUrl) .setPath("/rpc/pakin/loc/v1") .setJson(JSON.toJSONString(param)) .build() .doPost(); JSONObject jsonObject = JSON.parseObject(response); Integer code = jsonObject.getInteger("code"); if (code.equals(200)) { MessageQueue.offer(SlaveType.Devp, devpSlave.getId(), new Task(2, staProtocol)); devpThread.setPakMk(staProtocol.getSiteId(), false); News.info("输送线入库命令下发,任务数据={}", JSON.toJSON(wrkMast)); StartupDto dto = jsonObject.getObject("data", StartupDto.class); // String wmsLocNo = dto.getLocNo(); // int row = Integer.parseInt(wmsLocNo.substring(0, 2)); // int bay = Integer.parseInt(wmsLocNo.substring(2, 5)); // int lev = Integer.parseInt(wmsLocNo.substring(5, 7)); // String wcsLocNo = Utils.getLocNo(row, bay, lev); // // CreateInTaskParam createInTaskParam = new CreateInTaskParam(); // createInTaskParam.setTaskNo(String.valueOf(dto.getWorkNo())); // createInTaskParam.setDestLoc(wcsLocNo); // createInTaskParam.setOriginSite(dto.getSourceStaNo().toString()); // createInTaskParam.setDestSite(dto.getStaNo().toString()); // createInTaskParam.setPriority(11); // createInTaskParam.setBarcode(barcode); // // R result = openUtils.createInTask(createInTaskParam); // News.info("创建入库任务,任务数据={},WMS响应={},请求响应={}", JSON.toJSON(param), JSON.toJSON(jsonObject), JSON.toJSON(result)); // try{ // String msg = ""; // HashMap<String, String> hashMap = new HashMap<>(); // hashMap.put("msg", msg); // hashMap.put("sta", inSta.getStaNo().toString()); // new HttpHandler.Builder() // .setUri(wmsUrl) // .setPath("/rpc/led/getError") // .setJson(JSON.toJSONString(hashMap)) // .build() // .doPost(); // }catch (Exception e){ // // } } else { String msg = jsonObject.getString("msg"); HashMap<String, String> hashMap = new HashMap<>(); hashMap.put("msg", msg); hashMap.put("sta", inSta.getStaNo().toString()); new HttpHandler.Builder() .setUri(wmsUrl) .setPath("/rpc/led/getError") .setJson(JSON.toJSONString(hashMap)) .build() .doPost(); News.error("入库申请失败,任务数据={},请求响应={}", JSON.toJSON(param), JSON.toJSON(jsonObject)); } } catch (Exception e) { e.printStackTrace(); } } } } catch (Exception e) { e.printStackTrace(); } } /** * 初始化实时地图 @@ -494,7 +750,7 @@ } } else { Object object = redisUtil.get(RedisKeyType.SHUTTLE_WORK_FLAG.key + shuttleProtocol.getTaskNo()); if(object != null){ if (object != null) { ShuttleAssignCommand assignCommand = JSON.parseObject(object.toString(), ShuttleAssignCommand.class); if (!assignCommand.getAuto()) { //手动模式 @@ -1191,7 +1447,7 @@ } int errorCode = Integer.parseInt(shuttleProtocol.getErrorCode()); BasShuttleErr basShuttleErr = basShuttleErrService.queryByCode(errorCode); String errName = basShuttleErr==null? "未知异常":basShuttleErr.getErrName(); String errName = basShuttleErr == null ? "未知异常" : basShuttleErr.getErrName(); BasShuttleErrLog basShuttleErrLog = new BasShuttleErrLog( null, // 编号 wrkMast.getWrkNo(), // 工作号 @@ -1263,7 +1519,7 @@ } BasLiftErr basLiftErr = basLiftErrService.queryByCode(Integer.parseInt(liftProtocol.getErrorCode())); String errName = basLiftErr==null? "未知异常":basLiftErr.getErrName(); String errName = basLiftErr == null ? "未知异常" : basLiftErr.getErrName(); BasLiftErrLog basLiftErrLog = new BasLiftErrLog( null, // 编号 @@ -1367,7 +1623,7 @@ ArrayList<String> locs = new ArrayList<>(); locs.add(charge.getLocNo()); Integer checkHasShuttle = Utils.checkGroupLocHasShuttle(locs); if(checkHasShuttle != null) { if (checkHasShuttle != null) { //当前充电桩有穿梭车,不分配该充电桩 continue; } @@ -1417,7 +1673,7 @@ //查询小车充电任务 for (ShuttleSlave shuttle : slaveProperties.getShuttle()) { WrkMast wrkMast = wrkMastService.selectChargeWorking(shuttle.getId()); if(wrkMast == null) { if (wrkMast == null) { continue; } @@ -1503,7 +1759,7 @@ //判断是否存在未完成的移动任务 WrkMast moveWrk = wrkMastService.selectShuttleHasMoveWorking(wrkMast.getShuttleNo()); if(moveWrk != null) { if (moveWrk != null) { return false; } @@ -1604,7 +1860,7 @@ } BasShuttleCharge basShuttleCharge = basShuttleChargeService.selectOne(new EntityWrapper<BasShuttleCharge>().eq("charge_id", wrkMast.getMk())); if(basShuttleCharge == null) { if (basShuttleCharge == null) { return false; } @@ -1636,7 +1892,7 @@ this.shuttleMoveExecuteTransportLift(wrkMast); } else if ("TRANSPORT_DEVP".equals(wrkMast.getMk())) { }else { } else { this.shuttleMoveExecuteMove(wrkMast); } } @@ -1682,7 +1938,7 @@ if (Utils.getRow(liftLocNo) == Utils.getRow(wrkMast.getSourceLocNo()) && Utils.getBay(liftLocNo) == Utils.getBay(wrkMast.getSourceLocNo())) { //取货位置是提升机 this.shuttleMoveExecuteTransportLiftTake(wrkMast); }else { } else { //放货位置是提升机 this.shuttleMoveExecuteTransportLiftPut(wrkMast); } @@ -1907,7 +2163,7 @@ wrkMast.setSystemMsg("");//清空消息 wrkMastService.updateById(wrkMast); return false; }else { } else { liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo()); if (liftThread == null) { News.info("{}号提升机不存在", wrkMast.getLiftNo()); @@ -2371,7 +2627,7 @@ wrkMast.setSystemMsg("");//清空消息 wrkMastService.updateById(wrkMast); return false; }else { } else { liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo()); if (liftThread == null) { News.info("{}号提升机不存在", wrkMast.getLiftNo()); @@ -2934,7 +3190,7 @@ return false;//路径解锁失败 } commands.addAll(moveCommands); }else { } else { //小车在待机位,直接移动完成 wrkMast.setWrkSts(WrkStsType.MOVE_SITE_COMPLETE.sts);// 302.小车移动至站点 ==> 303.小车移动至站点完成 wrkMast.setModiTime(now); @@ -3134,7 +3390,7 @@ wrkMast.setSystemMsg("");//清空消息 wrkMastService.updateById(wrkMast); return false; }else { } else { liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo()); if (liftThread == null) { News.info("{}号提升机不存在", wrkMast.getLiftNo()); src/main/java/com/zy/core/MainProcess.java
@@ -40,6 +40,12 @@ if (!SystemProperties.WCS_RUNNING_STATUS.get()) { continue; } //zhangc //输送线 // 入库 ===>> 入库站到堆垛机站,根据条码扫描生成入库工作档 mainService.generateInboundWrk(); // 组托 //初始化实时地图 mainService.initRealtimeBasMap(); src/main/java/com/zy/core/ServerBootstrap.java
@@ -5,9 +5,11 @@ import com.zy.core.cache.MessageQueue; import com.zy.core.cache.SlaveConnection; import com.zy.core.enums.SlaveType; import com.zy.core.model.*; import com.zy.core.model.DevpSlave; import com.zy.core.model.ForkLiftSlave; import com.zy.core.model.LiftSlave; import com.zy.core.model.ShuttleSlave; import com.zy.core.properties.SlaveProperties; import com.zy.core.thread.*; import com.zy.core.thread.impl.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -46,7 +48,7 @@ News.info("核心控制层已启动..............................................."); } private void initMq(){ private void initMq() { // 初始化货叉提升机mq for (Slave forkLift : slaveProperties.getForkLift()) { MessageQueue.init(SlaveType.ForkLift, forkLift); @@ -61,7 +63,7 @@ } } private void initThread(){ private void initThread() { // 初始化货叉提升机 for (ForkLiftSlave forkLiftSlave : slaveProperties.getForkLift()) { News.info("初始化货叉提升机........................................................"); @@ -119,6 +121,33 @@ new Thread(thread).start(); SlaveConnection.put(SlaveType.Shuttle, shuttleSlave.getId(), thread); } // 初始化输送线 for (DevpSlave devpSlave : slaveProperties.getDevpSlave()) { News.info("初始化输送线......................................................"); ThreadHandler thread = null; if (devpSlave.getThreadImpl().equals("FyDevpThread")) { thread = new FyDevpThread(devpSlave); } else { throw new CoolException("未知的线程实现"); } new Thread(thread).start(); SlaveConnection.put(SlaveType.Shuttle, devpSlave.getId(), thread); } // 初始化电视机 for (DevpSlave devpSlave : slaveProperties.getL()) { News.info("初始化电视机......................................................"); ThreadHandler thread = null; if (devpSlave.getThreadImpl().equals("FyDevpThread")) { thread = new FyDevpThread(devpSlave); } else { throw new CoolException("未知的线程实现"); } new Thread(thread).start(); SlaveConnection.put(SlaveType.Shuttle, devpSlave.getId(), thread); } } src/main/java/com/zy/core/cache/MessageQueue.java
@@ -24,6 +24,8 @@ private static final Map<Integer, ConcurrentLinkedQueue<Task>> FORK_LIFT_EXCHANGE = new ConcurrentHashMap<>(); //货叉提升机Master mq交换机 private static final Map<Integer, ConcurrentLinkedQueue<Task>> FORK_LIFT_MASTER_EXCHANGE = new ConcurrentHashMap<>(); //显示屏mq交换机 private static final Map<Integer, ConcurrentLinkedQueue<Task>> LED_EXCHANGE = new ConcurrentHashMap<>(); /** * mq 交换机初始化 @@ -44,6 +46,9 @@ break; case Devp: DEVP_EXCHANGE.put(slave.getId(), new ConcurrentLinkedQueue<>()); break; case Led: LED_EXCHANGE.put(slave.getId(), new ConcurrentLinkedQueue<>()); break; default: break; @@ -66,6 +71,8 @@ return LIFT_EXCHANGE.get(id).offer(task); case Devp: return DEVP_EXCHANGE.get(id).offer(task); case Led: return LED_EXCHANGE.get(id).offer(task); default: return false; } @@ -87,6 +94,8 @@ return LIFT_EXCHANGE.get(id).poll(); case Devp: return DEVP_EXCHANGE.get(id).poll(); case Led: return LED_EXCHANGE.get(id).poll(); default: return null; } @@ -107,12 +116,14 @@ return LIFT_EXCHANGE.get(id).peek(); case Devp: return DEVP_EXCHANGE.get(id).peek(); case Led: return LED_EXCHANGE.get(id).peek(); default: return null; } } public static void clear(SlaveType type, Integer id){ public static void clear(SlaveType type, Integer id) { switch (type) { case Shuttle: SHUTTLE_EXCHANGE.get(id).clear(); @@ -129,6 +140,9 @@ case Devp: DEVP_EXCHANGE.get(id).clear(); break; case Led: LED_EXCHANGE.get(id).clear(); break; default: break; } src/main/java/com/zy/core/enums/SlaveType.java
@@ -7,6 +7,7 @@ Lift, ForkLift, ForkLiftMaster, Led ; public static SlaveType findInstance(String s){ src/main/java/com/zy/core/model/command/LedCommand.java
New file @@ -0,0 +1,36 @@ package com.zy.core.model.command; import com.zy.common.model.MatDto; import lombok.Data; import java.util.ArrayList; import java.util.List; /** * led命令报文 * Created by vincent on 2020/8/11 */ @Data public class LedCommand extends Object { private String title; private String workNo; private Integer staNo; private Integer sourceStaNo; private String locNo; private String sourceLocNo; private List<MatDto> matDtos = new ArrayList<>(); private boolean emptyMk = false; private Integer ioType; private String barcode; } src/main/java/com/zy/core/model/protocol/StaProtocol.java
@@ -20,13 +20,29 @@ // 目标站 private Short staNo; // 完结工作号 private Short finishWorkNo; // ---------------------------------------------------------------- // 自动 private boolean autoing; //空闲 private boolean idle; // 条码 private String barcode; //重量 private Integer weight; // 有物 private boolean loading; // 库位号 private String locNo; // 可入 private boolean inEnable; src/main/java/com/zy/core/properties/SlaveProperties.java
@@ -23,6 +23,10 @@ private int groupCount; private List<LedS> Led = new ArrayList<>(); private List<DevpSlave> devpSlave = new ArrayList<>(); private List<ShuttleSlave> shuttle = new ArrayList<>(); private List<LiftSlave> lift = new ArrayList<>(); src/main/java/com/zy/core/thread/LedThread.java
New file @@ -0,0 +1,23 @@ package com.zy.core.thread; import com.zy.core.ThreadHandler; import com.zy.core.model.command.LedCommand; import java.util.List; public interface LedThread extends ThreadHandler { void write(List<LedCommand> commands); void reset(); void error(String error); void errorReset(); void setLedMk(boolean mk); boolean isLedMk(); } src/main/java/com/zy/core/thread/impl/FyDevpThread.java
New file @@ -0,0 +1,319 @@ package com.zy.core.thread.impl; import HslCommunication.Core.Types.OperateResult; import HslCommunication.Core.Types.OperateResultExOne; 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.BasDevp; import com.zy.asrs.service.BasDevpService; import com.zy.core.News; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.OutputQueue; import com.zy.core.enums.SlaveType; import com.zy.core.model.DevpSlave; import com.zy.core.model.Task; import com.zy.core.model.protocol.StaProtocol; import com.zy.core.thread.DevpThread; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 输送线线程 * Created by vincent on 2020/8/4 */ @Data @Slf4j public class FyDevpThread implements Runnable, DevpThread { private DevpSlave slave; private SiemensS7Net siemensS7Net; private Map<Integer, StaProtocol> station = new ConcurrentHashMap<>(); private short heartBeatVal = 1; private int barcodeSize = 10; //写 public static final ArrayList<Integer> staNos1 = new ArrayList<Integer>() {{ add(1012); add(1014); add(1015); add(1022); add(1023); add(1025); add(1026); add(1031); add(1032); }}; //读 public static final ArrayList<Integer> staNos2 = new ArrayList<Integer>() {{ add(1011); add(1012); add(1013); add(1014); add(1015); add(1021); add(1022); add(1023); add(1024); add(1025); add(1026); add(1031); add(1032); }}; public FyDevpThread(DevpSlave slave) { this.slave = slave; } @Override @SuppressWarnings("InfiniteLoopStatement") public void run() { connect(); while (true) { try { int step = 1; Task task = MessageQueue.poll(SlaveType.Devp, slave.getId()); if (task != null) { step = task.getStep(); } switch (step) { // 读数据 case 1: read(); break; // 写数据 ID+目标站 case 2: write((StaProtocol) task.getData()); read(); break; default: break; } // 心跳 // heartbeat(); Thread.sleep(400); } catch (Exception e) { e.printStackTrace(); } } } @Override public boolean connect() { boolean result = false; siemensS7Net = new SiemensS7Net(SiemensPLCS.S1500, slave.getIp()); siemensS7Net.setRack(slave.getRack().byteValue()); siemensS7Net.setSlot(slave.getSlot().byteValue()); OperateResult connect = siemensS7Net.ConnectServer(); 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())); News.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())); News.error("输送线plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); } // siemensS7Net.ConnectClose(); return result; } /** * 读取状态 ====> 整块plc */ private void read() throws InterruptedException { int staNoSize = staNos2.size(); OperateResultExOne<byte[]> result = siemensS7Net.Read("DB82.14", (short) (staNoSize * 26)); if (result.IsSuccess) { for (int i = 0; i < staNoSize; i++) { Integer siteId = staNos2.get(i); StaProtocol staProtocol = station.get(staNos2.get(i)); if (null == staProtocol) { staProtocol = new StaProtocol(); staProtocol.setSiteId(siteId); if (siteId == 1015) { staProtocol.setLocNo("1200301"); } else if (siteId == 1026) { staProtocol.setLocNo("1200305"); } station.put(siteId, staProtocol); } Thread.sleep(300); boolean[] status = siemensS7Net.getByteTransform().TransBool(result.Content, i * 26, 2); staProtocol.setAutoing(status[0]); // 自动 staProtocol.setIdle(status[1]); //空闲 staProtocol.setLoading(status[2]); // 有物 staProtocol.setBackErr(status[5]); staProtocol.setLeftErr(status[6]); staProtocol.setRightErr(status[7]); staProtocol.setHighErr(status[8]); staProtocol.setWeightErr(status[9]); staProtocol.setLow(status[10]); staProtocol.setHigh(status[11]); staProtocol.setInEnable(status[13]); // 可入 staProtocol.setOutEnable(status[14]);// 可出 staProtocol.setWorkNo(siemensS7Net.getByteTransform().TransInt16(result.Content, i * 26 + 2)); // 工作号 staProtocol.setStaNo((short) siemensS7Net.getByteTransform().TransInt16(result.Content, i * 26 + 4)); // 目标站 staProtocol.setFinishWorkNo(siemensS7Net.getByteTransform().TransInt16(result.Content, i * 26 + 6)); //已完成工作号 staProtocol.setBarcode(siemensS7Net.getByteTransform().TransString(result.Content, i * 26 + 10, 12, "UTF-8").trim()); //条码 staProtocol.setWeight(siemensS7Net.getByteTransform().TransInt32(result.Content, i * 26 + 22)); //重量 if (!staProtocol.isPakMk() && !staProtocol.isLoading()) { staProtocol.setPakMk(true); } } } if (!Cools.isEmpty(result) && result.IsSuccess) { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功", DateUtils.convert(new Date()), slave.getId())); // 根据实时信息更新数据库 try { List<BasDevp> stations = new ArrayList<>(); for (Integer sta : staNos2) { StaProtocol staProtocol = station.get(sta); BasDevp sqlModel = staProtocol.toSqlModel(); stations.add(sqlModel); } if (!stations.isEmpty()) { BasDevpService basConveyorStaService = SpringUtils.getBean(BasDevpService.class); if (null != basConveyorStaService && !basConveyorStaService.updateBatchById(stations)) { throw new Exception("更新数据库数据失败"); } } } catch (Exception e) { e.printStackTrace(); OutputQueue.DEVP.offer(MessageFormat.format("【{0}】更新数据库数据失败 ===>> [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("更新数据库数据失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()); } } 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())); // log.error("读取输送线plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", device.getId(), device.getIp(), device.getPort(), device.getRack(), device.getSlot()); } } /** * 写入 ID+目标站 =====> 单站点写入 */ private void write(StaProtocol staProtocol) throws InterruptedException { if (null == staProtocol) { return; } int index = staNos1.indexOf(staProtocol.getSiteId()); index += 1; short[] array = new short[2]; array[0] = staProtocol.getWorkNo(); array[1] = staProtocol.getStaNo(); String staNoAddress = "DB83." + (index * 8 + 4); String workNoAddress = "DB83." + (index * 8 + 6); OperateResult write1 = null; // 工作号 OperateResult write2 = null; // 目标站 //任务下发次数 int writeCount = 0; do { write1 = siemensS7Net.Write(workNoAddress, array[0]); // 工作号 write2 = siemensS7Net.Write(staNoAddress, array[1]); if ((write1.IsSuccess && write2.IsSuccess)) { log.info("写入输送线命令后返回成功,并且回读成功。输送线plc编号={},{},{},写入次数={}", staProtocol.getSiteId(), JSON.toJSON(staProtocol.getWorkNo()), JSON.toJSON(staProtocol.getStaNo()), writeCount); // OperateResultExOne<byte[]> readResult = siemensS7Net.Read("DB82.14", (short) (staNos2.indexOf(siteId) * 26)); // //OperateResultExOne<byte[]> readResult = siemensS7Net.Read(staNoAddress, (short) 8); // if (readResult.IsSuccess) { // int workNo2 = siemensS7Net.getByteTransform().TransInt16(readResult.Content, 2); // 工作号 // int staNo2 = siemensS7Net.getByteTransform().TransInt16(readResult.Content, 4); // 目标站 // // int staNo2 = siemensS7Net.getByteTransform().TransInt16(readResult.Content, 0); // //int workNo2 = siemensS7Net.getByteTransform().TransInt16(readResult.Content, 0); // if (workNo == workNo2 && staNo == staNo2) { // //任务命令写入成功 // log.info("写入输送线命令后返回成功,并且回读成功。输送线plc编号={},{},{},写入次数={}", siteId, JSON.toJSON(workNo), JSON.toJSON(staNo), writeCount); // return true; // } else {//返回结果是成功了,但是真实值不相同 // writeCount++; // log.error("写入输送线命令后返回成功,但是读取任务值不一致。输送线plc编号={},{},{},写入次数={}", siteId, JSON.toJSON(workNo), JSON.toJSON(staNo), writeCount); // } // } else { // writeCount++; // log.error("写入输送线命令后读取失败。输送线plc编号={},站点数据={},{},写入次数={}", siteId, JSON.toJSON(workNo), JSON.toJSON(staNo), writeCount); // } } else { writeCount++; } } while (writeCount < 5); // StaProtocol staProtocol = station.get(siteId); // if (staProtocol.getWorkNo() == 0 && staProtocol.getStaNo() ==0) { // staProtocol.setPakMk(true); // } OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(array))); log.error("写入输送线站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(array)); } /** * 心跳 */ private void heartbeat() { if (heartBeatVal == 1) { heartBeatVal = 2; } else { heartBeatVal = 1; } OperateResult write = siemensS7Net.Write("DB100.50", heartBeatVal); if (!write.IsSuccess) { News.error("输送线plc编号={} 心跳失败", slave.getId()); } } /** * 设置入库标记 */ @Override public void setPakMk(Integer siteId, boolean pakMk) { StaProtocol staProtocol = station.get(siteId); if (null != staProtocol) { staProtocol.setPakMk(pakMk); } } public synchronized void setOutInModel(Short staNo, Short outInModel) { String dbAddress = "DB51.4"; if (staNo == 105) { dbAddress = "DB51.4"; } else if (staNo == 205) { dbAddress = "DB51.10"; } else if (staNo == 346) { dbAddress = "DB51.12"; } else { News.error("模式切换失败,地址错误={},model={}", staNo, outInModel); return; } OperateResult write = siemensS7Net.Write(dbAddress, outInModel); if (!write.IsSuccess) { News.error("模式切换失败={},model={}", staNo, outInModel); } } @Override public void close() { siemensS7Net.ConnectClose(); } } src/main/java/com/zy/core/thread/impl/NormalLedThread.java
New file @@ -0,0 +1,88 @@ package com.zy.core.thread.impl; import com.zy.common.model.MatDto; import com.zy.core.model.command.LedCommand; import com.zy.core.thread.LedThread; import lombok.extern.slf4j.Slf4j; import java.util.HashSet; import java.util.List; import java.util.Set; @Slf4j @SuppressWarnings("all") public class NormalLedThread implements LedThread, Runnable { private Set<Integer> workNos = new HashSet<>(); private boolean ledMk = false; private boolean resetStatus = false; // 复位状态 // 显示器 private StringBuffer stringBuffer = new StringBuffer(); private List<LedCommand> commandList; private StringBuffer errorMsg = new StringBuffer(); @Override public void run() { } public void write(List<LedCommand> list) { commandList = list; StringBuilder sb = new StringBuilder(); for (LedCommand command : list) { sb.append(command.getTitle()).append("(").append(command.getWorkNo()).append(")").append("\n"); sb.append("源库位:").append(command.getSourceLocNo()).append("\n"); sb.append("目标站:").append(command.getStaNo()).append("\n"); if (!command.isEmptyMk()) { for (MatDto matDto : command.getMatDtos()) { sb.append("物料编码:").append(matDto.getMatNo()).append("\n"); sb.append("名称:").append(matDto.getMaknx()).append("\n"); sb.append("数量:").append(matDto.getCount()).append("\n"); sb.append("规格:").append(matDto.getSpecs()).append("\n"); } } sb.append("\n"); } stringBuffer.delete(0, stringBuffer.length()); stringBuffer.append(sb.toString()); errorReset(); } public void reset() { commandList = null; stringBuffer.delete(0, stringBuffer.length()); errorMsg.delete(0, errorMsg.length()); } public void error(String msg) { errorMsg.delete(0, errorMsg.length()); errorMsg.append(msg); } public void errorReset() { this.errorMsg.delete(0, errorMsg.length()); } @Override public boolean connect() { return true; } @Override public void close() { } @Override public void setLedMk(boolean mk) { this.ledMk = mk; } @Override public boolean isLedMk() { return this.ledMk; } } src/main/java/com/zy/core/thread/impl/SiemensDevpThread.java
File was deleted src/main/resources/application.yml
@@ -13,7 +13,7 @@ driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/fyxc_shuttle?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: root password: zhangchao mvc: static-path-pattern: /** redis: @@ -44,14 +44,14 @@ # 下位机配置 wcs-slave: # # 四向穿梭车1 # shuttle[0]: # id: 1 # ip: 192.168.10.81 # port: 8888 # rack: 0 # slot: 0 # threadImpl: NyShuttleThread # # 四向穿梭车1 # shuttle[0]: # id: 1 # ip: 192.168.10.81 # port: 8888 # rack: 0 # slot: 0 # threadImpl: NyShuttleThread # 四向穿梭车2 shuttle[0]: id: 2 @@ -72,3 +72,15 @@ standByBay: 1 staRow: 2 staBay: 1 devpSlave[0]: id: inSta[0]: staNo: backSta: inSta[1]: staNo: backSta: