现场调试修改

This commit is contained in:
lsymicc
2026-09-08 22:23:58 +08:00
parent f944d7fef5
commit 7a7532f8bd
38 changed files with 1099 additions and 599 deletions

View File

@@ -7,9 +7,12 @@ import com.ruoyi.device.ssj.domain.DeviceSsj;
import com.ruoyi.device.ssj.service.IDeviceSsjService;
import com.ruoyi.common.domain.PlcConnectInfo;
import com.ruoyi.schedule.plcRead.ddj.PlcDdj1Read;
import com.ruoyi.schedule.plcRead.ddj.PlcDdj2Read;
import com.ruoyi.schedule.plcRead.ssj.PlcSsjRead;
import com.ruoyi.common.domain.CustomThread;
import com.ruoyi.schedule.scheduleTask.ddj.DdjThread;
import com.ruoyi.schedule.scheduleTask.ddj.DdjThread_1;
import com.ruoyi.schedule.scheduleTask.ddj.DdjThread_2;
import com.ruoyi.schedule.scheduleTask.monit.MonitoringThread;
import com.ruoyi.schedule.scheduleTask.ssj.PortConvThread;
import com.ruoyi.schedule.scheduleTask.ssj.RoadConvThread;
@@ -33,19 +36,22 @@ public class ScheduleThread {
public CustomThread<PlcSsjRead> plcSsjReadCustomThread;
public CustomThread<PlcDdj1Read> plcDdj1ReadCustomThread;
// public CustomThread<PlcDdj2Read> plcDdj2ReadCustomThread;
public CustomThread<PlcDdj2Read> plcDdj2ReadCustomThread;
public CustomThread<PortConvThread> portConvCustomThread;
public CustomThread<RoadConvThread> roadConvCustomThread;
public CustomThread<MonitoringThread> monitoringCustomThread;
public CustomThread<DdjThread> ddj1CustomThread;
public CustomThread<DdjThread> ddjCustomThread;
public CustomThread<DdjThread_1> ddj1CustomThread;
public CustomThread<DdjThread_2> ddj2CustomThread;
@Autowired
private IDeviceSsjService deviceSsjService;
@Autowired
private IMsgDdjService msgDdjService;
private boolean isRun = false;
// private boolean isRun1 = false;
private boolean isRun2 = false;
/**
@@ -77,8 +83,10 @@ public class ScheduleThread {
RoadConvThread roadConvThread = new RoadConvThread();
roadConvCustomThread = new CustomThread<RoadConvThread>(new Thread(roadConvThread), roadConvThread);
DdjThread ddj1Thread = new DdjThread();
ddj1CustomThread = new CustomThread<DdjThread>(new Thread(ddj1Thread), ddj1Thread);
DdjThread_1 ddj1Thread = new DdjThread_1();
DdjThread_2 ddj2Thread = new DdjThread_2();
ddj1CustomThread = new CustomThread<DdjThread_1>(new Thread(ddj1Thread), ddj1Thread);
ddj2CustomThread = new CustomThread<DdjThread_2>(new Thread(ddj2Thread), ddj2Thread);
}
/**
@@ -98,7 +106,7 @@ public class ScheduleThread {
//获取堆垛机
ConcurrentHashMap<String, MsgDdj> ddj1List = new ConcurrentHashMap<>();
// ConcurrentHashMap<String, MsgDdj> ddj2List = new ConcurrentHashMap<>();
ConcurrentHashMap<String, MsgDdj> ddj2List = new ConcurrentHashMap<>();
List<MsgDdj> msgDdjs = msgDdjService.selectMsgDdjList(new MsgDdj());
for (MsgDdj msgDdj : msgDdjs) {
msgDdj.setPlcDbReadAddress(msgDdj.getPlcDbReadAddress());
@@ -110,13 +118,13 @@ public class ScheduleThread {
ddj1List.put("ddj1", msgDdj);
PlcDdj1Read.deviceDdjMap = ddj1List;
break;
// case 2:
// PlcDdj2Read plcDdj2Read = new PlcDdj2Read(msgDdj, new PlcConnectInfo(msgDdj.getIp(), Convert.toInt(msgDdj.getPort())));
// Thread plcDdj2ReadThread = new Thread(plcDdj2Read);
// plcDdj2ReadCustomThread = new CustomThread<PlcDdj2Read>(plcDdj2ReadThread, plcDdj2Read);
// ddj2List.put("ddj2", msgDdj);
// PlcDdj2Read.deviceDdjMap = ddj2List;
// break;
case 2:
PlcDdj2Read plcDdj2Read = new PlcDdj2Read(msgDdj, new PlcConnectInfo(msgDdj.getIp(), Convert.toInt(msgDdj.getPort())));
Thread plcDdj2ReadThread = new Thread(plcDdj2Read);
plcDdj2ReadCustomThread = new CustomThread<PlcDdj2Read>(plcDdj2ReadThread, plcDdj2Read);
ddj2List.put("ddj2", msgDdj);
PlcDdj2Read.deviceDdjMap = ddj2List;
break;
}
}
}
@@ -127,7 +135,7 @@ public class ScheduleThread {
public void startAllThread() {
plcSsjReadCustomThread.getThread().start();
plcDdj1ReadCustomThread.getThread().start();
// plcDdj2ReadCustomThread.getThread().start();
plcDdj2ReadCustomThread.getThread().start();
isRun = true;
}
@@ -139,6 +147,7 @@ public class ScheduleThread {
portConvCustomThread.thread.start();
roadConvCustomThread.thread.start();
ddj1CustomThread.thread.start();
ddj2CustomThread.thread.start();
isRun2 = true;
}
@@ -148,7 +157,7 @@ public class ScheduleThread {
public void stopAllThread() {
plcSsjReadCustomThread.runnable.isRun = false;
plcDdj1ReadCustomThread.runnable.isRun = false;
// plcDdj2ReadCustomThread.runnable.isRun = false;
plcDdj2ReadCustomThread.runnable.isRun = false;
plcReadInit();
isRun = false;
}
@@ -162,6 +171,7 @@ public class ScheduleThread {
roadConvCustomThread.runnable.isRun = false;
ddj1CustomThread.runnable.isRun = false;
ddj2CustomThread.runnable.isRun = false;
scheduleInit();
isRun2 = false;
}

View File

@@ -39,8 +39,9 @@ public class PlcDdj1Read extends Thread {
try {
if (IsConnect()) {
readPlcDdj(msgDdj);
Thread.sleep(800);
Thread.sleep(1000);
} else {
Thread.sleep(2000);
reConnect();
}
} catch (InterruptedException e) {
@@ -54,7 +55,7 @@ public class PlcDdj1Read extends Thread {
}
private void readPlcDdj(MsgDdj msgDdj) {
OperateResultExOne<byte[]> read2 = readWriteNet.Read(msgDdj.getPlcDbReadAddress(), Convert.toShort("38"));
OperateResultExOne<byte[]> read2 = readWriteNet.Read(msgDdj.getPlcDbReadAddress(), Convert.toShort("32"));
String ddsx = "0";
if (read2.IsSuccess) {
ddsx = SoftBasic.ByteToHexString(read2.Content);
@@ -71,6 +72,7 @@ public class PlcDdj1Read extends Thread {
msgDdj.setMbch(ParseUtil.optInt(22, ddsx));
msgDdj.setYxxf(ParseUtil.optInt(24, ddsx));
msgDdj.setXtxh(ParseUtil.optInt(26, ddsx));
msgDdj.setHeight(ParseUtil.optInt(30, ddsx));
msgDdj.setCurrentRow(ParseUtil.optInt(12, ddsx));
msgDdj.setCurrentColumn(ParseUtil.optInt(14, ddsx));

View File

@@ -39,8 +39,9 @@ public class PlcDdj2Read extends Thread {
try {
if (IsConnect()) {
readPlcDdj(msgDdj);
Thread.sleep(800);
Thread.sleep(1000);
} else {
Thread.sleep(2000);
reConnect();
}
} catch (InterruptedException e) {
@@ -54,7 +55,7 @@ public class PlcDdj2Read extends Thread {
}
private void readPlcDdj(MsgDdj msgDdj) {
OperateResultExOne<byte[]> read2 = readWriteNet.Read(msgDdj.getPlcDbReadAddress(), Convert.toShort("38"));
OperateResultExOne<byte[]> read2 = readWriteNet.Read(msgDdj.getPlcDbReadAddress(), Convert.toShort("34"));
String ddsx = "0";
if (read2.IsSuccess) {
ddsx = SoftBasic.ByteToHexString(read2.Content);
@@ -71,10 +72,12 @@ public class PlcDdj2Read extends Thread {
msgDdj.setMbch(ParseUtil.optInt(22, ddsx));
msgDdj.setYxxf(ParseUtil.optInt(24, ddsx));
msgDdj.setXtxh(ParseUtil.optInt(26, ddsx));
msgDdj.setDqxd(ParseUtil.optInt(30, ddsx));
msgDdj.setHeight(ParseUtil.optInt(32, ddsx));
msgDdj.setCurrentRow(ParseUtil.optInt(26, ddsx));
msgDdj.setCurrentColumn(ParseUtil.optInt(26, ddsx));
msgDdj.setCurrentFloor(ParseUtil.optInt(26, ddsx));
msgDdj.setCurrentRow(ParseUtil.optInt(12, ddsx));
msgDdj.setCurrentColumn(ParseUtil.optInt(14, ddsx));
msgDdj.setCurrentFloor(ParseUtil.optInt(16, ddsx));
}
}

View File

@@ -53,15 +53,16 @@ public class PlcSsjRead implements Runnable {
DeviceSsj ssjDevice = deviceSsjMap.get(ssjCode);
switch (ssjDevice.getType()) {
case "1":
readPlcInOutSsj(ssjDevice);//出入口输送机
readPlcInSsj(ssjDevice);//出库输送机
break;
case "2":
readPlcRoadWaySsj(ssjDevice);//巷道输送机
readPlcRoadWaySsj(ssjDevice);//巷道输送机(入库)
break;
}
}
Thread.sleep(800);
Thread.sleep(1000);
} else {
Thread.sleep(2000);
reConnect();
}
} catch (InterruptedException e) {
@@ -77,29 +78,30 @@ public class PlcSsjRead implements Runnable {
/**
* 其他输送机
* 出库输送机 1001 1004 1006 1008
*
* @param ssjDevice
*/
private void readPlcOtherSsj(DeviceSsj ssjDevice) {
OperateResultExOne<byte[]> read2 = readWriteNet.Read(ssjDevice.getPlcDbReadAddress(), Short.parseShort("10"));
private void readPlcInSsj(DeviceSsj ssjDevice) {
OperateResultExOne<byte[]> read2 = readWriteNet.Read(ssjDevice.getPlcDbReadAddress(), Short.parseShort("12"));
String ddsx1 = "0";
if (read2.IsSuccess) {
ddsx1 = SoftBasic.ByteToHexString(read2.Content);
ssjDevice.setKx(ParseUtil.optInt(0, ddsx1));
ssjDevice.setDw(ParseUtil.optInt(2, ddsx1));
ssjDevice.setSszt(ParseUtil.optInt(0, ddsx1));
ssjDevice.setKx(ParseUtil.optInt(2, ddsx1));
ssjDevice.setDw(ParseUtil.optInt(4, ddsx1));
ssjDevice.setTaskNo(ParseUtil.optDInt(6, ddsx1));
}
}
/**
* 入出库输送机
* 入库输送机 1003 1005 1007 1010
*
* @param ssjDevice
*/
private void readPlcInOutSsj(DeviceSsj ssjDevice) {
OperateResultExOne<byte[]> read2 = readWriteNet.Read(ssjDevice.getPlcDbReadAddress(), Short.parseShort("30"));
private void readPlcRoadWaySsj(DeviceSsj ssjDevice) {
OperateResultExOne<byte[]> read2 = readWriteNet.Read(ssjDevice.getPlcDbReadAddress(), Short.parseShort("26"));
String ddsx1 = "0";
if (read2.IsSuccess) {
ddsx1 = SoftBasic.ByteToHexString(read2.Content);
@@ -110,19 +112,19 @@ public class PlcSsjRead implements Runnable {
ssjDevice.setRkqq(ParseUtil.optInt(10, ddsx1));
ssjDevice.setHeight(ParseUtil.optInt(12, ddsx1));
ssjDevice.setTraySize(ParseUtil.optInt(12, ddsx1)); //此处不修改device_ssj表,把托盘尺寸值当作高度使用
ssjDevice.setTrayCode(ParseUtil.optString(14, ddsx1).replaceAll("\\s", ""));
ssjDevice.setMode(ParseUtil.optInt(24, ddsx1));//todo 输送机操作模式
ssjDevice.setException(ParseUtil.optInt(28, ddsx1));
ssjDevice.setException(ParseUtil.optInt(14, ddsx1));
ssjDevice.setTrayCode(ParseUtil.optString(18, ddsx1).replaceAll("\\s", ""));
// ssjDevice.setMode(ParseUtil.optInt(24, ddsx1));//todo 输送机操作模式
}
}
/**
* 巷道输送机
* 出入口输送机
*
* @param ssjDevice
*/
private void readPlcRoadWaySsj(DeviceSsj ssjDevice) {
private void readPlcInOutSsj(DeviceSsj ssjDevice) {
OperateResultExOne<byte[]> read2 = readWriteNet.Read(ssjDevice.getPlcDbReadAddress(), Short.parseShort("10"));
String ddsx1 = "0";
if (read2.IsSuccess) {

View File

@@ -46,7 +46,7 @@ public class ParseUtil {
*/
public static String optString(int start, String data) {
byte[] bytes = SoftBasic.HexStringToBytes(data.substring(start * 2, (start + 7) * 2));
byte[] bytes = SoftBasic.HexStringToBytes(data.substring(start * 2, (start + 8) * 2));
return Tools.bytetostringtool(bytes);
}

View File

@@ -1,30 +1,51 @@
package com.ruoyi.schedule.scheduleTask;
import HslCommunication.Profinet.Siemens.SiemensPLCS;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.api.domain.agv.ResponseBase;
import com.ruoyi.api.domain.wcs2wms.JobParam;
import com.ruoyi.api.domain.wcs2wms.ResponseResult;
import com.ruoyi.api.domain.wcs2wms.exception.TaskExceptionReceive;
import com.ruoyi.api.domain.wcs2wms.exception.TaskExceptionRequest;
import com.ruoyi.api.domain.wcs2wms.stockin.StockinReceive;
import com.ruoyi.api.service.IApiService;
import com.ruoyi.api.service.IRequestLogService;
import com.ruoyi.bas.cargospace.domain.BasCargoSpace;
import com.ruoyi.bas.cargospace.service.IBasCargoSpaceService;
import com.ruoyi.common.ConvType;
import com.ruoyi.common.TaskStatusCode;
import com.ruoyi.common.TaskType;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.device.ddj.domain.MsgDdj;
import com.ruoyi.device.ddj.service.IMsgDdjService;
import com.ruoyi.job.domain.MydoJob;
import com.ruoyi.job.service.IJobCallBackService;
import com.ruoyi.job.service.IMydoJobService;
import com.ruoyi.queue.ddj.domain.DdjDeviceExecutionQueue;
import com.ruoyi.queue.ddj.domain.DdjDeviceExecutionQueueFinish;
import com.ruoyi.queue.ddj.service.IDdjDeviceExecutionQueueFinishService;
import com.ruoyi.queue.ddj.service.IDdjDeviceExecutionQueueService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import static com.ruoyi.common.TaskExceptionType.TASK_EXCEPTION_STOCKIN_OCCUPIED;
import static com.ruoyi.common.TaskStatusCode.*;
import static com.ruoyi.common.WmsTaskTypeCode.WMS_TASK_TYPE_EXCEPTION;
import static com.ruoyi.schedule.plcRead.ssj.PlcSsjRead.writeToSsj;
/**
* 处理wcs执行作业的定时任务类
@@ -43,6 +64,15 @@ public class TaskHandler {
private IApiService apiService;
@Autowired
private IDdjDeviceExecutionQueueService ddjDeviceExecutionQueueService;
@Autowired
IDdjDeviceExecutionQueueFinishService ddjDeviceExecutionQueueFinishService;
@Autowired
IMsgDdjService ddjService;
@Autowired
IRequestLogService requestLogService;
// private SiemensS7Net siemens = new SiemensS7Net(SiemensPLCS.S1500, "192.168.56.60");
private static final int TIMEINTERVAL_DEFAULT = 2000;
@@ -62,7 +92,11 @@ public class TaskHandler {
);
if (!jobs.isEmpty()) {
for (MydoJob job : jobs) {
mydoJobService.taskFinish(Long.valueOf(job.getTaskNo()));
if (!job.getInOrOut().equals(TaskType.TASKTYPE_STOCKOUT) &&
!job.getInOrOut().equals(TaskType.TASKTYPE_STOCKOUT_PICK) &&
!job.getInOrOut().equals(TaskType.TASKTYPE_STOCKOUT_MANUAL)) {
mydoJobService.taskFinish(Long.valueOf(job.getTaskNo()));
}
}
}
}
@@ -105,7 +139,7 @@ public class TaskHandler {
/**
* 【超时自动完成】 - 处理未正常移除的【堆垛机执行完成】或【出库到位】的遗留任务
*/
@Scheduled(fixedDelay = TIMEINTERVAL_10000)
// @Scheduled(fixedDelay = TIMEINTERVAL_10000)
public void finishMydoJobTimeout(){
List<MydoJob> jobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().status(TASK_EP_DDJ_FINISH_TIMEOUT).build()
@@ -241,41 +275,310 @@ public class TaskHandler {
if (!jobs.isEmpty()) {
for (MydoJob job : jobs) {
stackerTask(job);
//获取重分的货位重新向堆垛机下发任务
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(job.getCargoSpaceId());
DdjDeviceExecutionQueue ddjDeviceExecutionQueue =
ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByRwh(Long.valueOf(job.getTaskNo()), Integer.valueOf(job.getRoadwayId()));
ddjDeviceExecutionQueue.setMbph(basCargoSpace.getThePlatoon());
ddjDeviceExecutionQueue.setMblh(basCargoSpace.getTheColumn());
ddjDeviceExecutionQueue.setMbch(basCargoSpace.getTheFloor());
ddjDeviceExecutionQueue.setDdjxf("0");
ddjDeviceExecutionQueueService.updateDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
}
}
}
/**
* 更新堆垛机任务队列 - 异常盘点重新下发
* @param mydoJob
* 【更新作业状态】 - 巷道口到位生成堆垛机【取货】作业
*/
public void stackerTask(MydoJob mydoJob) {
//获取重分的货位重新向堆垛机下发任务
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(mydoJob.getCargoSpaceId());
DdjDeviceExecutionQueue ddjDeviceExecutionQueue =
ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByRwh(Long.valueOf(mydoJob.getTaskNo()), Integer.valueOf(mydoJob.getRoadwayId()));
ddjDeviceExecutionQueue.setMbph(basCargoSpace.getThePlatoon());
ddjDeviceExecutionQueue.setMblh(basCargoSpace.getTheColumn());
ddjDeviceExecutionQueue.setMbch(basCargoSpace.getTheFloor());
ddjDeviceExecutionQueue.setDdjxf("0");
ddjDeviceExecutionQueueService.updateDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
@Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT)
public void updateStackerPickStatus() {
List<MydoJob> jobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().status(TASK_STATUS_RUNNING).executionPhase(TASK_EP_ROADWAY_SSJ).build()
);
if (jobs.isEmpty()) return;
for (MydoJob job : jobs) {
// 生成堆垛机取货队列
if (Convert.toInt(job.getInOrOut()) >= 20) continue;
//弯轨堆垛机设备编号使用货位区域编号对应
int devId = 2;
if (job.getRoadwayId().equals("1")) {
devId = 1;
}
//检查堆垛机是否在正在执行中/已经有执行队列
List<DdjDeviceExecutionQueue> ddjDeviceExecutionQueues = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(
new DdjDeviceExecutionQueue().builder().devId(devId).build()
);
//取货位置
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(
ConvType.CONV_ROAD_CARGO.get(job.getEntranceId())
);
MsgDdj msgDdj = ddjService.selectMsgDdjById(Long.valueOf(devId));
//生成堆垛机执行队列
//生成取货作业时货叉必须有货 - 即【货叉状态】不为0
if (CollUtil.isEmpty(ddjDeviceExecutionQueues) && msgDdj.getHczt() == 0) {
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueue.setUuid(IdUtil.simpleUUID());
ddjDeviceExecutionQueue.setRwh(Convert.toLong(job.getTaskNo()));
ddjDeviceExecutionQueue.setDevName(job.getRoadwayId());
ddjDeviceExecutionQueue.setDevId(devId);
ddjDeviceExecutionQueue.setRwzt(0);
ddjDeviceExecutionQueue.setYph(Convert.toInt(basCargoSpace.getThePlatoon()));
ddjDeviceExecutionQueue.setYlh(Convert.toInt(basCargoSpace.getTheColumn()));
ddjDeviceExecutionQueue.setYch(Convert.toInt(basCargoSpace.getTheFloor()));
ddjDeviceExecutionQueue.setMbph(Convert.toInt(basCargoSpace.getThePlatoon()));
ddjDeviceExecutionQueue.setMblh(1);
ddjDeviceExecutionQueue.setMbch(1);
ddjDeviceExecutionQueue.setDdjxf("0");
ddjDeviceExecutionQueue.setMlfs(3);//3-取货
// ddjDeviceExecutionQueue.setSpare1(job.getTraySize().toString());//货物高度
ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date()));
// ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_3);
ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
log.info("【堆垛机执行】{}#堆垛机生成入库<取货>队列,任务号:{}", devId, job.getTaskNo());
}
}
}
/**
* 查询正在执行的堆垛机队列是否为遗留记录 - 清理遗留队列数据
* 【更新作业状态】 - 取货完成--→请求wms并生成堆垛机放货任务
*/
// @Scheduled(fixedDelay = 30000)
public void clearStackerQueue(){
// ddjDeviceExecutionQueueService.se
}
@Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT)
public void updateStackerPutStatus(){
@PostConstruct
public void mpTest(){
List<MydoJob> jobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().status(TASK_STATUS_RUNNING).executionPhase(TASK_EP_DDJ_PICK).build()
);
if (jobs.isEmpty()) return;
for (MydoJob job : jobs) {
DdjDeviceExecutionQueue queue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByTaskNo(job.getTaskNo());
DdjDeviceExecutionQueueFinish queueFinish = new DdjDeviceExecutionQueueFinish();
if (ObjUtil.isNotNull(queue)){
BeanUtils.copyProperties(queue, queueFinish);
//插入历史
ddjDeviceExecutionQueueFinishService.insertDdjDeviceExecutionQueueFinish(queueFinish);
//移除队列
ddjDeviceExecutionQueueService.deleteDdjDeviceExecutionQueueByTaskNo(job.getTaskNo());
log.info("【堆垛机执行】移除堆垛机入库取货队列,任务号:{}", job.getTaskNo());
}
Long ddjId = Convert.toInt(job.getRoadwayId()) == 1 ? 1L : 2L;
MsgDdj msgDdj = ddjService.selectMsgDdjById(ddjId);
if (msgDdj.getYxxf() != 1) continue;
if (msgDdj.getSbzt() != 0) continue;
if (msgDdj.getCzfs() != 5) continue;
if (msgDdj.getHeight() == 0) continue;
if (msgDdj.getHczt() == 0) continue;//货叉有货才能继续请求货位
//请求wms获取作业号和货位
//初始化请求wms参数
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("reqCode", UUID.randomUUID().toString());//请求码
paramMap.put("trayCode", job.getTrayCode().trim());//容器编号
paramMap.put("entranceId", job.getEntranceId());//入口输送机编号
paramMap.put("roadwayId", job.getRoadwayId());//入口输送机编号对应巷道/区域
paramMap.put("cargoAreaId", ConvType.CONV_ROAD_AREA.get(job.getEntranceId()));//入口输送机编号对应巷道/区域
paramMap.put("height", msgDdj.getHeight());//高度
// paramMap.put("remark", errorMessage);
AjaxResult ajaxResult;
String errorMessage = "";
/*-----------------请求生成wcs任务----------------- */
ajaxResult = apiService.createMydoJobForStockin(paramMap);
if (ajaxResult.isSuccess()) {
if (job.getExecutionPhase().equals(TASK_EP_DDJ_PICK)){
job.setExecutionPhase(TASK_EP_DDJ);
mydoJobService.updateMydoJob(job);
}
//解析wms下发的响应参数(任务号和货位)
ResponseBase res = JSON.parseObject(ajaxResult.get("msg").toString(), ResponseBase.class);
StockinReceive result = BeanUtil.toBean(res.getData(), StockinReceive.class);
//校验:wms分配的货位(排列层)是否合法
if (ObjUtil.isNull(basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(result.getCargoSpaceId()))) {
errorMessage = "wms下发货位错误,任务生成失败!";
paramMap.put("remark", errorMessage);
// apiService.createInMydoJobException(paramMap);
log.info("【响应参数异常】异常货位:{},无法生成作业,托盘条码:{}", result.getCargoSpaceId(), job.getTrayCode());
return;
}
job.setJobId(result.getJobId());
job.setInOrOut(result.getInOrOut());
job.setCargoSpaceId(result.getCargoSpaceId());
mydoJobService.updateMydoJob(job);
log.info(
"【堆垛机入库请求】请求wms分配货位成功,wms作业号:{}, wcs任务号:{},分配货位:{}", job.getJobId(), job.getTaskNo(), job.getCargoSpaceId()
);
//生成堆垛机<放货>队列
// 检查任务属性:【任务已存在】、执行阶段-【巷道口输送机到位】、任务类型-【入库】 → 下发堆垛机执行队列
if (Convert.toInt(job.getInOrOut()) < 20) {
//弯轨堆垛机设备编号使用货位区域编号对应
int devId = 2;
if (basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(job.getCargoSpaceId()).getCargoAreaId().equals("01")){
devId = 1;
}
//检查堆垛机是否在正在执行中/已经有执行队列
List<DdjDeviceExecutionQueue> ddjDeviceExecutionQueues = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(
new DdjDeviceExecutionQueue().builder().devId(devId).build()
);
//目标位置
BasCargoSpace basCargoSpacePut = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(job.getCargoSpaceId());
//取货位置
BasCargoSpace basCargoSpacePick = basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(
ConvType.CONV_ROAD_CARGO.get(job.getEntranceId())
);
//生成堆垛机执行队列
if (CollUtil.isEmpty(ddjDeviceExecutionQueues) && ObjUtil.isNotNull(basCargoSpacePut) && msgDdj.getHczt() != 0) {
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueue.setUuid(IdUtil.simpleUUID());
ddjDeviceExecutionQueue.setRwh(Convert.toLong(job.getTaskNo()));
ddjDeviceExecutionQueue.setDevName("ddj" + devId);
ddjDeviceExecutionQueue.setDevId(devId);
ddjDeviceExecutionQueue.setRwzt(0);
ddjDeviceExecutionQueue.setYph(basCargoSpacePick.getThePlatoon());
ddjDeviceExecutionQueue.setYlh(basCargoSpacePick.getTheColumn());
ddjDeviceExecutionQueue.setYch(basCargoSpacePick.getTheFloor());
ddjDeviceExecutionQueue.setMbph(Convert.toInt(basCargoSpacePut.getThePlatoon()));
ddjDeviceExecutionQueue.setMblh(Convert.toInt(basCargoSpacePut.getTheColumn()));
ddjDeviceExecutionQueue.setMbch(Convert.toInt(basCargoSpacePut.getTheFloor()));
ddjDeviceExecutionQueue.setDdjxf("0");
ddjDeviceExecutionQueue.setMlfs(4);//4-放货
// ddjDeviceExecutionQueue.setSpare1(job.getTraySize().toString());//货物高度
ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date()));
// ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_3);
ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
log.info("【堆垛机执行】{}#堆垛机生成入库放货作业,wcs任务号:{}", Long.valueOf(job.getRoadwayId()), job.getTaskNo());
}
}
}else{
// 接口调用失败处理
log.info("【入库请求】请求分配货位失败,请检查网络或请求参数,请求内容:{}", JSON.toJSONString(paramMap));
log.info("【错误信息】{}", requestLogService.selectRequestLogByLatestTask().getErrorDetails());
// 请求生成wcs任务失败
//todo 向堆垛机下发退回
}
}
}
/**
* 【移库作业】 - 取放
*/
@Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT)
public void sendStackerMoveJob() {
List<MydoJob> jobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().status(TASK_STATUS_CREATED).executionPhase(TASK_EP_CREATED).inOrOut(TaskType.TASKTYPE_MOVE_STR).build()
);
if (jobs.isEmpty()) return;
for (MydoJob job : jobs) {
//弯轨堆垛机设备编号使用货位区域编号对应
int devId = 2;
if (job.getRoadwayId().equals("1")) {
devId = 1;
}
//检查堆垛机是否在正在执行中/已经有执行队列
List<DdjDeviceExecutionQueue> ddjDeviceExecutionQueues = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(
new DdjDeviceExecutionQueue().builder().devId(devId).build()
);
//取货位置
BasCargoSpace basCargoSpacePick = basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(
job.getCargoSpaceId()
);
//放货位置
BasCargoSpace basCargoSpacePut = basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(
job.getTargetCargoSpaceId()
);
MsgDdj msgDdj = ddjService.selectMsgDdjById(Long.valueOf(devId));
//生成堆垛机执行队列
//生成取货作业时货叉必须有货 - 即【货叉状态】不为0
if (CollUtil.isEmpty(ddjDeviceExecutionQueues) && msgDdj.getHczt() == 0) {
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueue.setUuid(IdUtil.simpleUUID());
ddjDeviceExecutionQueue.setRwh(Convert.toLong(job.getTaskNo()));
ddjDeviceExecutionQueue.setDevName(job.getRoadwayId());
ddjDeviceExecutionQueue.setDevId(devId);
ddjDeviceExecutionQueue.setRwzt(0);
ddjDeviceExecutionQueue.setYph(Convert.toInt(basCargoSpacePick.getThePlatoon()));
ddjDeviceExecutionQueue.setYlh(Convert.toInt(basCargoSpacePick.getTheColumn()));
ddjDeviceExecutionQueue.setYch(Convert.toInt(basCargoSpacePick.getTheFloor()));
ddjDeviceExecutionQueue.setMbph(Convert.toInt(basCargoSpacePut.getThePlatoon()));
ddjDeviceExecutionQueue.setMblh(Convert.toInt(basCargoSpacePut.getTheColumn()));
ddjDeviceExecutionQueue.setMbch(Convert.toInt(basCargoSpacePut.getTheFloor()));
ddjDeviceExecutionQueue.setDdjxf("0");
ddjDeviceExecutionQueue.setMlfs(5);//
// ddjDeviceExecutionQueue.setSpare1(job.getTraySize().toString());//货物高度
ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date()));
// ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_3);
ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
if (job.getExecutionPhase().equals(TASK_EP_CREATED) && job.getStatus().equals(TASK_STATUS_CREATED)){
job.setExecutionPhase(TASK_EP_DDJ);
job.setExecutionPhase(TASK_STATUS_RUNNING);
mydoJobService.updateMydoJob(job);
}
log.info("【堆垛机执行】{}#堆垛机生成移库<取放>队列,任务号:{}", devId, job.getTaskNo());
}
}
}
}

View File

@@ -68,33 +68,33 @@ public class DdjThread implements Runnable {
@Override
public void run() {
init();
while (isRun) {
for (String type : ddjCodeList.keySet()) {
if ("ddj".equals(type)) {
for (String ddjCode : ddjCodeList.get(type)) {
try {
if ("ddj1".equals(ddjCode)) {
// ddjTask(PlcDdj1Read.deviceDdjMap.get(ddjCode));
}
//PlcDdj2Read.deviceDdjMap.containsKey(ddjCode)
// if ("ddj2".equals(ddjCode)) {
// ddjTask(PlcDdj2Read.deviceDdjMap.get(ddjCode));
// init();
// while (isRun) {
// for (String type : ddjCodeList.keySet()) {
//
// if ("ddj".equals(type)) {
// for (String ddjCode : ddjCodeList.get(type)) {
// try {
// if ("ddj1".equals(ddjCode)) {
//// ddjTask(PlcDdj1Read.deviceDdjMap.get(ddjCode));
// }
} catch (RuntimeException e) {
log.error(e.getMessage(), e);
}
}
}
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
// //PlcDdj2Read.deviceDdjMap.containsKey(ddjCode)
//// if ("ddj2".equals(ddjCode)) {
//// ddjTask(PlcDdj2Read.deviceDdjMap.get(ddjCode));
//// }
// } catch (RuntimeException e) {
// log.error(e.getMessage(), e);
// }
//
// }
// }
// }
// try {
// Thread.sleep(3000);
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
// }
}
@@ -145,11 +145,6 @@ public class DdjThread implements Runnable {
}
/* -------------------------------------- 【3 放货有货,重新分配货位】-------------------------------------- */
// ddj.setCzfs(5);
// ddj.setSbzt(1052);
// ddj.setYxxf(1);
// ddj.setJdbz(4);
// ddj.setRwh(85015L);
// 1.联机自动【5】 2.设备状态-放货有货【1052】 3.执行阶段【0】【5】(无执行中的任务)
if (ddj.getSbzt() == 1052 && ddj.getJdbz() < 5 && ddj.getYxxf() == 1) {
@@ -211,14 +206,6 @@ public class DdjThread implements Runnable {
// -------------------------------------- 4 取货无货,作废当前任务,重新分配单据 --------------------------------------
//测试数据
// ddj.setCzfs(5);
// ddj.setSbzt(1053);
// ddj.setYxxf(1);
// ddj.setJdbz(3);
// ddj.setRwh(20021L);
// ddj.setId(1);
// 1.联机自动【5】 2.设备状态-取货无货【1053】 3.执行阶段【<5】(任务执行中)
if (ddj.getSbzt() == 1053 && ddj.getJdbz() < 5) {
Long rwh = ddj.getRwh();
@@ -292,7 +279,7 @@ public class DdjThread implements Runnable {
}
//正常下发
if (ddj.getYxxf() == 1 && ddj.getSbzt() == 0 ) {
if (ddj.getYxxf() == 1 && ddj.getSbzt() == 0) {
//检查是否有正在执行的堆垛机队列
Long rwh = ddj.getRwh();
DdjDeviceExecutionQueue ddjDeviceExecutionQueueRunningParam = new DdjDeviceExecutionQueue();

View File

@@ -76,7 +76,7 @@ public class DdjThread_1 implements Runnable {
}
}
try {
Thread.sleep(3000);
Thread.sleep(1500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
@@ -100,24 +100,32 @@ public class DdjThread_1 implements Runnable {
//完成作业
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(rwh);
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByRwh(rwh,ddj.getId());
//满足上述条件(【有实时任务】且【存在堆垛机执行队列】),表示该任务已完成-标记为已完成状态
if (mydoJob != null && ddjDeviceExecutionQueue != null) {
if (ddj.getHczt() == 0){
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByRwh(rwh,ddj.getId());
//标记为堆垛机执行完成
mydoJob.setExecutionPhase(TASK_EP_DDJ_FINISH);
mydoJobService.updateMydoJob(mydoJob);
//满足上述条件(【有实时任务】且【存在堆垛机执行队列】),表示该任务已完成-标记为已完成状态
if (mydoJob != null && ddjDeviceExecutionQueue != null) {
//执行wms回传 - 方法在存储过程【proc_mydojob_finish】中
// ddjTaskFinish(rwh, ddj.getId());
log.info("【堆垛机执行】设备编号:" + ddj.getId() + " 执行完成,任务结束,任务号:"+ddj.getRwh());
//标记为堆垛机执行完成
mydoJob.setExecutionPhase(TASK_EP_DDJ_FINISH);
mydoJobService.updateMydoJob(mydoJob);
log.info("【堆垛机执行】设备编号:" + ddj.getId() + " 执行完成,任务结束,任务号:"+ddj.getRwh());
}
}else{
if (mydoJob.getExecutionPhase().equals(TASK_EP_ROADWAY_SSJ)){
mydoJob.setExecutionPhase(TASK_EP_DDJ_PICK);
mydoJobService.updateMydoJob(mydoJob);
log.info("【更新状态】{}#堆垛机巷道口取货完成,等待下发放货任务,wcs任务号:{}", Long.valueOf(mydoJob.getRoadwayId()), mydoJob.getTaskNo());
}
}
}
//-------------------------------------- 【2 更新执行阶段】 --------------------------------------
// 1.联机自动【5】 2.设备状态 - 运行中【1】 3.执行阶段【2】
//-------------------------------------- 【2 更新执行阶段】 --------------------------------------
// 设备状态 - 运行中【1】 执行阶段【2】
if (ddj.getSbzt() == 1 && ddj.getJdbz() == 2) {
//根据堆垛机上任务号,修改任务执行阶段
@@ -132,12 +140,8 @@ public class DdjThread_1 implements Runnable {
}
}
/* -------------------------------------- 【3 放货有货,重新分配货位】-------------------------------------- */
// ddj.setCzfs(5);
// ddj.setSbzt(1052);
// ddj.setYxxf(1);
// ddj.setJdbz(4);
// ddj.setRwh(85015L);
// 1.联机自动【5】 2.设备状态-放货有货【1052】 3.执行阶段【0】【5】(无执行中的任务)
if (ddj.getSbzt() == 1052 && ddj.getJdbz() < 5 && ddj.getYxxf() == 1) {
@@ -163,15 +167,7 @@ public class DdjThread_1 implements Runnable {
}
// -------------------------------------- 4 取货无货,作废当前任务,重新分配单据 --------------------------------------
//测试数据
// ddj.setCzfs(5);
// ddj.setSbzt(1053);
// ddj.setYxxf(1);
// ddj.setJdbz(3);
// ddj.setRwh(20021L);
// ddj.setId(1);
// -------------------------------------- 【4 取货无货,作废当前任务,重新分配单据】 --------------------------------------
// 1.联机自动【5】 2.设备状态-取货无货【1053】 3.执行阶段【<5】(任务执行中)
if (ddj.getSbzt() == 1053 && ddj.getJdbz() < 5) {
Long rwh = ddj.getRwh();
@@ -211,8 +207,7 @@ public class DdjThread_1 implements Runnable {
// }
}
// -------------------------------------- 5 下发堆垛机任务 --------------------------------------
// -------------------------------------- 【5 下发堆垛机任务】 --------------------------------------
//重分货位后重下
if (ddj.getYxxf() == 1 && ddj.getSbzt() == 1052) {
Long rwh = ddj.getRwh();
@@ -244,8 +239,10 @@ public class DdjThread_1 implements Runnable {
}
}
//正常下发
if (ddj.getYxxf() == 1 && ddj.getSbzt() == 0 ) {
//检查是否有正在执行的堆垛机队列
Long rwh = ddj.getRwh();
DdjDeviceExecutionQueue ddjDeviceExecutionQueueRunningParam = new DdjDeviceExecutionQueue();
@@ -275,7 +272,7 @@ public class DdjThread_1 implements Runnable {
ddjDeviceExecutionQueueService.updateDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
log.info("【堆垛机入库】下发任务成功,任务执行中, 任务号:{}", ddjDeviceExecutionQueue.getRwh());
} else {
log.error("【堆垛机入库】执行异常, 堆垛机下发任务失败!");
log.error("【堆垛机入库】堆垛机下发任务失败,任务号:{},等待重新下发...", ddjDeviceExecutionQueue.getRwh());
}
}
}
@@ -316,12 +313,12 @@ public class DdjThread_1 implements Runnable {
int mbph = Convert.toInt(queue.getMbph());
int mblh = Convert.toInt(queue.getMblh());
int mbch = Convert.toInt(queue.getMbch());
int mlfs = 5;
int mlfs = queue.getMlfs();
int xfwc = 1;
int hwlx = Convert.toInt(queue.getSpare1());
// int hwlx = 0;//默认值
int jym = Tools.getJYM(taskNo, yph, ylh, ych, mbph, mblh, mbch, mlfs, hwlx);
byte[] sendData = Tools.sendDataToDevice(taskNo, null, yph, ylh, ych, mbph, mblh, mbch, mlfs, hwlx, xfwc, jym);
// int hwlx = Convert.toInt(queue.getSpare1());
int hwlx = 0;//默认值
int jym = Tools.getJYM(taskNo, yph, ylh, ych, mbph, mblh, mbch, mlfs);
byte[] sendData = Tools.sendDataToDevice(taskNo, null, yph, ylh, ych, mbph, mblh, mbch, mlfs, xfwc, jym);
if (devId==1){
return PlcDdj1Read.WriteToDDJ("DB61.0", sendData);
}else {
@@ -330,6 +327,4 @@ public class DdjThread_1 implements Runnable {
}
}

View File

@@ -66,7 +66,7 @@ public class DdjThread_2 implements Runnable {
for (String ddjCode : ddjCodeList.get(type)) {
try {
if ("ddj2".equals(ddjCode)) {
ddjTask(PlcDdj1Read.deviceDdjMap.get(ddjCode));
ddjTask(PlcDdj2Read.deviceDdjMap.get(ddjCode));
}
} catch (RuntimeException e) {
log.error(e.getMessage(), e);
@@ -76,7 +76,7 @@ public class DdjThread_2 implements Runnable {
}
}
try {
Thread.sleep(3000);
Thread.sleep(1500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
@@ -100,16 +100,27 @@ public class DdjThread_2 implements Runnable {
//完成作业
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(rwh);
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByRwh(rwh,ddj.getId());
//满足上述条件(【有实时任务】且【存在堆垛机执行队列】),表示该任务已完成-执行任务回传
if (mydoJob != null && ddjDeviceExecutionQueue != null) {
//标记为堆垛机执行完成
mydoJob.setExecutionPhase(TASK_EP_DDJ_FINISH);
mydoJobService.updateMydoJob(mydoJob);
//回传完成信号 - 方法在存储过程【proc_mydojob_finish】中
// ddjTaskFinish(rwh, ddj.getId());
log.info("【堆垛机入库】堆垛机编号:" + ddj.getId() + " 执行完成,任务结束,任务号:"+ddj.getRwh());
if (ddj.getHczt() == 0){
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueByRwh(rwh,ddj.getId());
//满足上述条件(【有实时任务】且【存在堆垛机执行队列】),表示该任务已完成-标记为已完成状态
if (mydoJob != null && ddjDeviceExecutionQueue != null) {
//标记为堆垛机执行完成
mydoJob.setExecutionPhase(TASK_EP_DDJ_FINISH);
mydoJobService.updateMydoJob(mydoJob);
log.info("【堆垛机执行】设备编号:" + ddj.getId() + " 执行完成,任务结束,任务号:"+ddj.getRwh());
}
}else{
if (mydoJob.getExecutionPhase().equals(TASK_EP_ROADWAY_SSJ)){
mydoJob.setExecutionPhase(TASK_EP_DDJ_PICK);
mydoJobService.updateMydoJob(mydoJob);
log.info("【更新状态】{}#堆垛机巷道口取货完成,等待下发放货任务,wcs任务号:{}", Long.valueOf(mydoJob.getRoadwayId()), mydoJob.getTaskNo());
}
}
}
@@ -210,7 +221,6 @@ public class DdjThread_2 implements Runnable {
}
// -------------------------------------- 5 下发堆垛机任务 --------------------------------------
//重分货位后重下
if (ddj.getYxxf() == 1 && ddj.getSbzt() == 1052) {
Long rwh = ddj.getRwh();
@@ -273,7 +283,7 @@ public class DdjThread_2 implements Runnable {
ddjDeviceExecutionQueueService.updateDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
log.info("【堆垛机入库】下发任务成功,任务执行中, 任务号:{}", ddjDeviceExecutionQueue.getRwh());
} else {
log.error("【堆垛机入库】执行异常, 堆垛机下发任务失败!");
log.error("【堆垛机入库】堆垛机下发任务失败,任务号:{},等待重新下发...", ddjDeviceExecutionQueue.getRwh());
}
}
}
@@ -314,12 +324,12 @@ public class DdjThread_2 implements Runnable {
int mbph = Convert.toInt(queue.getMbph());
int mblh = Convert.toInt(queue.getMblh());
int mbch = Convert.toInt(queue.getMbch());
int mlfs = 5;
int mlfs = queue.getMlfs();
int xfwc = 1;
int hwlx = Convert.toInt(queue.getSpare1());
// int hwlx = 0;//默认值
int jym = Tools.getJYM(taskNo, yph, ylh, ych, mbph, mblh, mbch, mlfs, hwlx);
byte[] sendData = Tools.sendDataToDevice(taskNo, null, yph, ylh, ych, mbph, mblh, mbch, mlfs, hwlx, xfwc, jym);
// int hwlx = Convert.toInt(queue.getSpare1());
int hwlx = 0;//默认值
int jym = Tools.getJYM(taskNo, yph, ylh, ych, mbph, mblh, mbch, mlfs);
byte[] sendData = Tools.sendDataToDevice(taskNo, null, yph, ylh, ych, mbph, mblh, mbch, mlfs, xfwc, jym);
if (devId==1){
return PlcDdj1Read.WriteToDDJ("DB61.0", sendData);
}else {

View File

@@ -87,46 +87,46 @@ public class MonitoringThread implements Runnable {
}
}
}
// for (String ddjCode : PlcDdj2Read.deviceDdjMap.keySet()) {
// MsgDdj msgDdj = PlcDdj2Read.deviceDdjMap.get(ddjCode);
// msgDdjService.updateMsgDdj(msgDdj);
//
// if (msgDdj.getSbzt() > 1000) {
// BasFaultRecord param = new BasFaultRecord();
// param.setTaskNo(msgDdj.getRwh() + "");
// param.setDeviceId(String.valueOf(msgDdj.getId()));
// param.setDeviceType("DDJ");
// param.setFault(msgDdj.getSbzt() + "");
// param.setJobId("0");
// List<BasFaultRecord> basFaultRecords = basFaultRecordService.selectBasFaultRecordList(param);
// if (CollUtil.isEmpty(basFaultRecords)) {
// BasFaultRecord faultRecord = new BasFaultRecord();
// faultRecord.setId(IdUtil.fastSimpleUUID());
// faultRecord.setDeviceId(String.valueOf(msgDdj.getId()));
// faultRecord.setDeviceName(msgDdj.getName());
// faultRecord.setDeviceType("DDJ");
// faultRecord.setJobId("0");
// faultRecord.setTaskNo(msgDdj.getRwh() + "");
// faultRecord.setFault(msgDdj.getSbzt() + "");
// faultRecord.setStartTime(DateUtil.formatDateTime(DateUtil.date()));
// //faultRecord.setWarehouseId(mydoJob.getWarehouseId());
// basFaultRecordService.insertBasFaultRecord(faultRecord);
// }
// }
// if (msgDdj.getSbzt() < 1000 && msgDdj.getCzfs() == 5){
// BasFaultRecord param = new BasFaultRecord();
// param.setDeviceId(String.valueOf(msgDdj.getId()));
// param.setDeviceType("DDJ");
// param.setJobId("0");
// List<BasFaultRecord> basFaultRecords = basFaultRecordService.selectBasFaultRecordList(param);
// if (CollUtil.isNotEmpty(basFaultRecords)) {
// BasFaultRecord faultRecord = basFaultRecords.get(0);
// faultRecord.setJobId("1");
// faultRecord.setFinishTime(DateUtil.formatDateTime(DateUtil.date()));
// basFaultRecordService.updateBasFaultRecord(faultRecord);
// }
// }
// }
for (String ddjCode : PlcDdj2Read.deviceDdjMap.keySet()) {
MsgDdj msgDdj = PlcDdj2Read.deviceDdjMap.get(ddjCode);
msgDdjService.updateMsgDdj(msgDdj);
if (msgDdj.getSbzt() > 1000) {
BasFaultRecord param = new BasFaultRecord();
param.setTaskNo(msgDdj.getRwh() + "");
param.setDeviceId(String.valueOf(msgDdj.getId()));
param.setDeviceType("DDJ");
param.setFault(msgDdj.getSbzt() + "");
param.setJobId("0");
List<BasFaultRecord> basFaultRecords = basFaultRecordService.selectBasFaultRecordList(param);
if (CollUtil.isEmpty(basFaultRecords)) {
BasFaultRecord faultRecord = new BasFaultRecord();
faultRecord.setId(IdUtil.fastSimpleUUID());
faultRecord.setDeviceId(String.valueOf(msgDdj.getId()));
faultRecord.setDeviceName(msgDdj.getName());
faultRecord.setDeviceType("DDJ");
faultRecord.setJobId("0");
faultRecord.setTaskNo(msgDdj.getRwh() + "");
faultRecord.setFault(msgDdj.getSbzt() + "");
faultRecord.setStartTime(DateUtil.formatDateTime(DateUtil.date()));
//faultRecord.setWarehouseId(mydoJob.getWarehouseId());
basFaultRecordService.insertBasFaultRecord(faultRecord);
}
}
if (msgDdj.getSbzt() < 1000 && msgDdj.getCzfs() == 5){
BasFaultRecord param = new BasFaultRecord();
param.setDeviceId(String.valueOf(msgDdj.getId()));
param.setDeviceType("DDJ");
param.setJobId("0");
List<BasFaultRecord> basFaultRecords = basFaultRecordService.selectBasFaultRecordList(param);
if (CollUtil.isNotEmpty(basFaultRecords)) {
BasFaultRecord faultRecord = basFaultRecords.get(0);
faultRecord.setJobId("1");
faultRecord.setFinishTime(DateUtil.formatDateTime(DateUtil.date()));
basFaultRecordService.updateBasFaultRecord(faultRecord);
}
}
}
try {
Thread.sleep(1500);
} catch (InterruptedException e) {

View File

@@ -34,7 +34,6 @@ import java.util.regex.Pattern;
import static com.ruoyi.common.TaskStatusCode.*;
import static com.ruoyi.common.TaskType.*;
import static com.ruoyi.common.WmsTaskTypeCode.WMS_TASK_TYPE_STOCKIN;
import static com.ruoyi.schedule.plcRead.ssj.PlcSsjRead.writeToSsj;
/**
@@ -60,7 +59,11 @@ public class PortConvThread implements Runnable {
public void init() {
ssjCodeList = new HashMap<>();
ArrayList<String> ssjCodes = new ArrayList<>();
ssjCodes.add("L1001");
ssjCodes.add("L1004");
ssjCodes.add("L1006");
ssjCodes.add("L1008");
ssjCodes.add("L1002");
ssjCodes.add("L1009");
ssjCodeList.put("portConv", ssjCodes);
apiService = SpringUtils.getBean(IApiService.class);
@@ -107,54 +110,34 @@ public class PortConvThread implements Runnable {
public void Schedule(DeviceSsj deviceSsj){
switch (deviceSsj.getDeviceCode()){
//1#巷道入库(单向)
case "L1009":
//3#巷道入库(单向)
case "L1002":
// 测试数据
// inSsjDevice.setInOrOut(1);
// inSsjDevice.setTrayCode("T000004503");
// inSsjDevice.setTaskNo(777778);
// inSsjDevice.setKx(0);
// inSsjDevice.setDw(1);
// inSsjDevice.setHeight(1);
// inSsjDevice.setWeight("100");
// inSsjDevice.setException(0);
// inSsjDevice.setRkqq(1);
//到位校验
if (!portConvChecked(deviceSsj)) return;
//更新入库任务阶段
updateMydoJob(deviceSsj);
//请求wms获取入库任务
requestMydoJob(deviceSsj);
break;
//1#巷道出库口(单向)
case "L1008":
//3#巷道出库口(单向)
case "L1001":
//出库完成
finishStockoutMydoJob(deviceSsj);
// finishStockoutMydoJob(deviceSsj);
//盘点出库
finishInventoryStockoutMydoJob(deviceSsj);
break;
//2#巷道出库口(双向)
//1#巷道/区域01出库口(双向)
case "L1002":
//3#巷道/区域03出库口(双向)
case "L1009":
//2#巷道/区域02出库口(双向)
case "L1004":
//2#巷道出库口(双向)
//2#巷道/区域03出库口(双向)
case "L1006":
//更新入库任务阶段
updateMydoJob(deviceSsj);
// updateMydoJob(deviceSsj);
//出库完成
finishStockoutMydoJob(deviceSsj);
//盘点出库
finishInventoryStockoutMydoJob(deviceSsj);
// finishInventoryStockoutMydoJob(deviceSsj);
break;
@@ -193,7 +176,6 @@ public class PortConvThread implements Runnable {
return true;
}
/**
* 请求wms获取wcs任务参数
* @param inSsjDevice
@@ -210,7 +192,6 @@ public class PortConvThread implements Runnable {
return;
}
String errorMessage = "";
AjaxResult ajaxResult;
@@ -220,9 +201,9 @@ public class PortConvThread implements Runnable {
paramMap.put("reqCode", UUID.randomUUID().toString());//请求码
paramMap.put("trayCode", inSsjDevice.getTrayCode().trim());//容器编号
// paramMap.put("entranceId", inSsjDevice.getDeviceCode());//入口输送机编号
paramMap.put("roadwayId", ConvType.CONV_ROAD.get(inSsjDevice.getDeviceCode()));//入口输送机编号对应巷道
paramMap.put("cargoAreaId", ConvType.CONV_ROAD_AREA.get(inSsjDevice.getDeviceCode()));//入口输送机编号对应巷道/区域
int height = inSsjDevice.getHeight();
// paramMap.put("trayType", height);//高度
paramMap.put("height", height);//高度
// paramMap.put("remark", errorMessage);
@@ -259,13 +240,13 @@ public class PortConvThread implements Runnable {
.trayCode(result.getTrayCode())
.cargoSpaceId(result.getCargoSpaceId())
// .wmsTaskNo(mydoJobService.getTaskNo("1"))
.traySize(String.valueOf(inSsjDevice.getHeight()))
.traySize(inSsjDevice.getHeight())
.inOrOut("1")
.roadwayId(basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(result.getCargoSpaceId()).getRoadwayId())//获取货位表货位对应的巷道号
.entranceId(inSsjDevice.getDeviceCode())
.executionPhase(TASK_EP_CREATED)
.faultFlag("0")
.priority(10L)
.priority(10)
.build();
@@ -288,6 +269,54 @@ public class PortConvThread implements Runnable {
}
}
/**
* 入口到位生成wcs本地作业
* @param inSsjDevice
*/
private void generateWcsMydoJob(DeviceSsj inSsjDevice){
//如果已经生成wcs任务则不继续执行后续请求操作
//包括请求成功生成作业和wms推送成功的情况
int count = mydoJobService.selectInOrOutMydoJobList(
new MydoJob().builder().trayCode(inSsjDevice.getTrayCode()).build()
).size();
if (count > 0) return;
//-----------------警告校验:条码已有库存-----------------
BasCargoSpace cargoSpace = new BasCargoSpace();
cargoSpace.setTrayCode(inSsjDevice.getTrayCode());
if (!basCargoSpaceService.selectBasCargoSpaceList(cargoSpace).isEmpty()) {
log.warn("【警告】该托盘号已有库存,托盘条码:{}",inSsjDevice.getTrayCode());
}
int trayType = mydoJobService.getTraytypeByTrayCode(inSsjDevice.getTrayCode());
//生成的任务初始化
MydoJob mydoJob = new MydoJob().builder()
// .jobId(result.getJobId())
.taskNo(mydoJobService.getTaskNo("2"))//如果需要用wms下发的任务号作为wcs的任务号使用
.status(TASK_STATUS_CREATED)
.trayCode(inSsjDevice.getTrayCode())
// .cargoSpaceId(result.getCargoSpaceId())
// .wmsTaskNo(mydoJobService.getTaskNo("1"))
.traySize(inSsjDevice.getHeight())
.inOrOut("1")
.roadwayId(String.valueOf(ConvType.CONV_ROAD_ROADWAY.get(inSsjDevice.getDeviceCode())))//获取货位表货位对应的巷道号
.entranceId(inSsjDevice.getDeviceCode())
.executionPhase(TASK_EP_CREATED)
.faultFlag("0")
.traySize(trayType)
.priority(10)
.build();
//如果还没有wcs任务 - 生成一条任务
if (mydoJobService.selectInOrOutMydoJobList(mydoJob).isEmpty()) {
mydoJobService.insertMydoJob(mydoJob);
log.info("【生成入库】本地生成wcs作业成功,wcs任务号:{},托盘条码:{}", mydoJob.getTaskNo(), mydoJob.getTrayCode());
}
}
/**
* 更新入库任务阶段
@@ -313,10 +342,10 @@ public class PortConvThread implements Runnable {
//写入成功则更新执行阶段
mydoJobStockin.setStatus(TASK_STATUS_RUNNING);
mydoJobStockin.setExecutionPhase(TASK_EP_SSJ);
mydoJobStockin.setEntranceId(inSsjDevice.getDeviceCode());
// mydoJobStockin.setEntranceId(inSsjDevice.getDeviceCode());
mydoJobStockin.setStartTime(DateUtil.formatDateTime(DateUtil.date()));
mydoJobService.updateMydoJob(mydoJobStockin);
log.info("【更新状态】G1009入口输送机下发成功,任务号:{},入库执行中", mydoJobStockin.getTaskNo());
log.info("【更新状态】入口输送机{}下发成功,任务号:{},入库执行中", inSsjDevice.getDeviceCode(), mydoJobStockin.getTaskNo());
}
}
@@ -341,14 +370,12 @@ public class PortConvThread implements Runnable {
mydoJobStockin.setExecutionPhase(TASK_EP_SSJ);
mydoJobStockin.setStartTime(DateUtil.formatDateTime(DateUtil.date()));
mydoJobService.updateMydoJob(mydoJobStockin);
log.info("【更新状态】入口输送机{}下发成功,任务号:{},盘点回库执行中", inSsjDevice.getDeviceCode(), mydoJobStockin.getTaskNo());
log.info("【更新状态】入口输送机{}下发成功,任务号:{},盘点回库执行中", inSsjDevice.getDeviceCode(), mydoJobStockin.getTaskNo());
}
}
}
/**
* 输送机出库到位 - 任务出库完成
* 出库完成在升降位置,即【TD1001】判断完成
@@ -359,24 +386,19 @@ public class PortConvThread implements Runnable {
if (outSsjDevice.getDw() == 1 && outSsjDevice.getTaskNo() > 0) {
//查询该出库任务
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Convert.toLong(outSsjDevice.getTaskNo()));
if (mydoJob != null && Integer.parseInt(mydoJob.getInOrOut()) == TASKTYPE_STOCKOUT) {
log.info("【出库完成】去向:{},出库货位:{},任务号:{},出库到位, 任务结束", outSsjDevice.getDeviceCode(),mydoJob.getCargoSpaceId() , mydoJob.getTaskNo());
if (ObjUtil.isNull(mydoJob)) return;
if (Integer.parseInt(mydoJob.getInOrOut()) >= 20 && Integer.parseInt(mydoJob.getInOrOut()) == TASKTYPE_INVENTORY) {
log.info("【出库到位】去向:{},出库货位:{},任务号:{},出库完成,等待确认执行回流操作, 任务结束", outSsjDevice.getDeviceCode(),mydoJob.getCargoSpaceId() , mydoJob.getTaskNo());
mydoJob.setExecutionPhase(TASK_EP_SSJ_STOCKOUT_FINISH);
mydoJobService.updateMydoJob(mydoJob);
mydoJobService.taskFinish(Long.valueOf(mydoJob.getTaskNo()));
}
//盘点任务出库到位不结束任务
if (mydoJob != null && Integer.parseInt(mydoJob.getInOrOut()) == TASKTYPE_STOCKOUT) {
log.info("【盘点出库完成】去向:{},出库货位:{},任务号:{},盘点出库到位, 等待盘点回库", outSsjDevice.getDeviceCode(),mydoJob.getCargoSpaceId() , mydoJob.getTaskNo());
mydoJob.setExecutionPhase(TASK_EP_SSJ_INVENTORY_STOCKOUT_FINISH);
mydoJobService.updateMydoJob(mydoJob);
}
}
}
/**
* 输送机出库到位 - 盘点任务出库阶段完成
* 出库完成在升降位置,即【TD1001】判断完成
@@ -387,89 +409,21 @@ public class PortConvThread implements Runnable {
if (outSsjDevice.getDw() == 1 && outSsjDevice.getTaskNo() > 0) {
//查询该出库任务
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Convert.toLong(outSsjDevice.getTaskNo()));
if (mydoJob != null && Integer.parseInt(mydoJob.getInOrOut()) == TASKTYPE_INVENTORY) {
log.info("【盘点出库完成】去向:{},出库货位:{},任务号:{},出库到位", "盘点出库完成,等待执行回库", outSsjDevice.getDeviceCode(),mydoJob.getCargoSpaceId() , mydoJob.getTaskNo());
if (ObjUtil.isNull(mydoJob)) return;
//盘点任务出库到位不结束任务
if (Integer.parseInt(mydoJob.getInOrOut()) == TASKTYPE_INVENTORY) {
log.info("【盘点出库完成】去向:{},出库货位:{},任务号:{},出库到位", "盘点出库完成,等待执行回流", outSsjDevice.getDeviceCode(),mydoJob.getCargoSpaceId() , mydoJob.getTaskNo());
mydoJob.setExecutionPhase(TASK_EP_SSJ_INVENTORY_STOCKOUT_FINISH);
mydoJobService.updateMydoJob(mydoJob);
// mydoJobService.taskFinish(Long.valueOf(mydoJob.getTaskNo()));
}
}
}
// ====== 【请按实际修改】======
private static final String MOXA_IP = "192.168.1.200"; // NPort 5110 的 IP
private static final int MOXA_PORT = 4001; // NPort 配置的 Local Port
private static final int RECONNECT_DELAY_SEC = 3; // 断线后重试间隔(秒)
private static final int SO_TIMEOUT_MS = 5000; // Socket 读超时(防卡死)
private static final Pattern WEIGHT_PATTERN = Pattern.compile(
"[+-]?\\d+\\.\\d{1,3}(?=[\\s\\r\\n]|kg|g|lb|$)"); // 匹配如 +12.34、-5.678、345.0kg
/**
* 从 MOXA NPort 5110(TCP Server 模式)读取单次称重值
* ************测试方法************
* ************测试方法************
* ************测试方法************
*
* @param moxaIp MOXA 设备 IP(如 "192.168.1.200")
* @param moxaPort MOXA 配置的 TCP 端口(如 4001)
* @param timeout 最大等待时间(单位:毫秒),建议 2000~5000
* @return 重量(kg),成功时为非 NaN 的 Double;失败(超时/断连/解析失败)返回 null
*/
public static Double getWeightByMoxa(String moxaIp, int moxaPort, long timeout) {
Socket socket = null;
try {
// 1️⃣ - 建立连接(带连接超时)
socket = new Socket();
socket.connect(new InetSocketAddress(moxaIp, moxaPort), 3000); // 连接超时 3s
socket.setSoTimeout((int) Math.min(timeout, Integer.MAX_VALUE)); // 读超时
// 2 - 发送请求指令(可选:仅当秤需指令才启用)
// OutputStream out = socket.getOutputStream();
// out.write("\r\n".getBytes(StandardCharsets.US_ASCII)); // 或 "\r", "W\r\n"
// out.flush();
// 3 - 读响应(使用 BufferedInputStream + 手动读字节,更健壮于无换行场景)
InputStream in = socket.getInputStream();
byte[] buffer = new byte[128];
int len = in.read(buffer);
if (len <= 0) return null;
String response = new String(buffer, 0, len, StandardCharsets.US_ASCII).trim();
if (response.isEmpty()) return null;
// 4 - 解析重量(兼容常见格式:+12.34、-5.678、00012.34kg、123.45\r\n)
Pattern p = Pattern.compile("[+-]?\\d*\\.?\\d+(?=[\\s\\r\\n]|kg|g|lb|$)");
java.util.regex.Matcher m = p.matcher(response);
if (m.find()) {
try {
double w = Double.parseDouble(m.group());
// 过滤明显异常值(可选)
if (Double.isFinite(w) && Math.abs(w) < 1e6) {
return w;
}
} catch (NumberFormatException ignored) {}
}
return null;
} catch (IOException e) {
return null; // 连接失败、读超时、解析异常等均返回 null
} finally {
if (socket != null && !socket.isClosed()) {
try { socket.close(); } catch (IOException ignored) {}
}
}
}
public void inDispatch1(DeviceSsj ssjDevice) {
//有入库请求就肯定是电气的任务号的作业
@@ -519,7 +473,7 @@ public class PortConvThread implements Runnable {
mydoJob2.setExecutionPhase(TASK_EP_CREATED);
mydoJob2.setCreateTime(new Date());
mydoJob2.setFaultFlag("0");
mydoJob2.setPriority(10L);
mydoJob2.setPriority(10);
mydoJobService.insertMydoJob(mydoJob2);
int i = writeToSsj(ssjDevice.getPlcDbWriteAddress(),mydoJob2.getTaskNo(),1,1);
if (i == 1) {

View File

@@ -5,9 +5,11 @@ import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.api.service.IApiService;
import com.ruoyi.bas.cargospace.domain.BasCargoSpace;
import com.ruoyi.bas.cargospace.service.IBasCargoSpaceService;
import com.ruoyi.common.ConvType;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.device.ssj.domain.DeviceSsj;
import com.ruoyi.job.domain.MydoJob;
@@ -20,9 +22,8 @@ import lombok.extern.slf4j.Slf4j;
import java.util.*;
import static com.ruoyi.common.ConvType.ROADWAY1_EXIT;
import static com.ruoyi.common.TaskStatusCode.*;
import static com.ruoyi.common.TaskType.*;
import static com.ruoyi.schedule.plcRead.ssj.PlcSsjRead.writeToSsj;
/**
* 巷道口输送机(堆垛机取放位)线程 检测当前巷道有没有入库作业,没有作业,生成堆垛机出库队列
@@ -43,8 +44,12 @@ public class RoadConvThread implements Runnable {
public void init() {
ssjCodeList = new HashMap<>();
ArrayList<String> ssjCodes = new ArrayList<>();
// ssjCodes.add("L1002");
ssjCodes.add("L1001");
ssjCodes.add("L1003");
ssjCodes.add("L1005");
ssjCodes.add("L1007");
ssjCodes.add("L1010");
ssjCodes.add("L1008");
ssjCodeList.put("roadConv", ssjCodes);
apiService = SpringUtils.getBean(IApiService.class);
agvQueueService = SpringUtils.getBean(IAgvQueueService.class);
@@ -53,8 +58,12 @@ public class RoadConvThread implements Runnable {
ddjDeviceExecutionQueueService = SpringUtils.getBean(IDdjDeviceExecutionQueueService.class);
//初始化巷道口 排 列 层
//todo 核对堆垛机取放位置的货位编码
roadwayMap.put("L1010", Arrays.asList(1, 1, 1));
// roadwayMap.put("L1004", Arrays.asList(4, 0, 1));
roadwayMap.put("L1001", Arrays.asList(2, 0, 1));
roadwayMap.put("L1003", Arrays.asList(3, 0, 1));
roadwayMap.put("L1005", Arrays.asList(5, 0, 1));
roadwayMap.put("L1007", Arrays.asList(7, 0, 1));
roadwayMap.put("L1010", Arrays.asList(10, 0, 1));
roadwayMap.put("L1008", Arrays.asList(11, 0, 1));
log.info("初始化服务 {},{}", apiService, agvQueueService);
}
@@ -71,7 +80,7 @@ public class RoadConvThread implements Runnable {
if (PlcSsjRead.deviceSsjMap.containsKey(ssjCode)) {
schedule(PlcSsjRead.deviceSsjMap.get(ssjCode));
} else {
log.error("设备不存在 ssjCode{}", ssjCode);
log.error("设备不存在:ssjCode{}", ssjCode);
}
} catch (RuntimeException e) {
log.error(e.getMessage(),e);
@@ -93,28 +102,58 @@ public class RoadConvThread implements Runnable {
public void schedule(DeviceSsj roadSsjDevice) {
switch (roadSsjDevice.getDeviceCode()){
//1#巷道入库(单向)
case "L1010":
//3#巷道入库(单向)
//1#巷道入库(双向)
case "L1003":
//3#巷道入库(双向)
case "L1010":
//到位校验
if (!roadConvChecked(roadSsjDevice)) return;
if (roadConvCheckedForStockin(roadSsjDevice)) {
//更新入库任务阶段
updateMydoJob(roadSsjDevice);
//更新入库任务阶段
sendStackerIn(roadSsjDevice);
//生成wcs本地作业
generateWcsMydoJob(roadSsjDevice);
};
//请求wms获取入库任务
//requestMydoJob(deviceSsj);
if (roadConvCheckedForStockout(roadSsjDevice)) {
sendStackerOut(roadSsjDevice);
}
break;
//1#巷道出库口(单向) -- FT577项目巷道1和巷道3出库位置为单输送机,故此处【出库完成】的方法移至端口输送机线程【PortConvThread】中执行
case "L1008":
//3#巷道出库口(单向)
//1#巷道出库口(单向)
// -- FT577项目巷道1和巷道3出库位置为单输送机,故此处【出库完成】的方法移至端口输送机线程【PortConvThread】中执行
//1001和1008作为盘点和手动出库口使用
case "L1001":
//出库完成
// finishStockoutMydoJob(deviceSsj);
sendStackerOut(roadSsjDevice);
//3#巷道出库口(单向)
case "L1008":
// if (roadConvCheckedForStockout(roadSsjDevice)) {
// sendStackerOut(roadSsjDevice);
// }
break;
//2#巷道/区域02出库口(双向)
case "L1005":
//3#巷道/区域03出库口(双向)
case "L1007":
//到位校验
if (roadConvCheckedForStockin(roadSsjDevice)) {
//更新入库任务阶段
updateMydoJob(roadSsjDevice);
//生成wcs本地作业
generateWcsMydoJob(roadSsjDevice);
}
if (roadConvCheckedForStockout(roadSsjDevice)) {
sendStackerOut(roadSsjDevice);
}
break;
}
@@ -123,90 +162,147 @@ public class RoadConvThread implements Runnable {
/**
* 输送机到位判断校验
* 输送机到位判断校验 - 入库
* @param inSsjDevice
* @return
*/
private boolean roadConvChecked(DeviceSsj inSsjDevice){
private boolean roadConvCheckedForStockin(DeviceSsj inSsjDevice){
boolean flag = false;
//---------------------------巷道口取放货输送机---------------------------
//输送机【任务号】和【到位】校验
if (inSsjDevice.getTaskNo() == 0 || inSsjDevice.getDw() == 0) return flag;
// if (inSsjDevice.getTaskNo() == 0 || inSsjDevice.getDw() == 0) return flag;
if (inSsjDevice.getRkqq() == 0) return flag;
//输送机条码不能为空
if (StrUtil.isBlank(inSsjDevice.getTrayCode())) return flag;
String cargoAreaId = String.valueOf(ConvType.CONV_ROAD_AREA.get(inSsjDevice.getDeviceCode()));
int trayType = mydoJobService.getTraytypeByTrayCode(inSsjDevice.getTrayCode());
if (cargoAreaId.equals("02")){
if (trayType != 3){
log.warn("【入库异常】托盘类型与货区{}不匹配,请检查条码格式,输送机:{},托盘码:{}", cargoAreaId, inSsjDevice.getDeviceCode(), inSsjDevice.getTrayCode());
writeToSsj(inSsjDevice.getPlcDbWriteAddress(), "99", 6, 2);
return false;
}
}else{
if (trayType == 3){
log.warn("【入库异常】托盘类型与货区{}不匹配,请检查条码格式,输送机:{},托盘码:{}", cargoAreaId, inSsjDevice.getDeviceCode(), inSsjDevice.getTrayCode());
writeToSsj(inSsjDevice.getPlcDbWriteAddress(), "99", 6, 2);
return false;
}
}
return true;
}
/**
* 输送机到位判断校验 - 出库
* @param inSsjDevice
* @return
*/
private boolean roadConvCheckedForStockout(DeviceSsj inSsjDevice){
boolean flag = false;
//---------------------------巷道口取放货输送机---------------------------
//输送机【任务号】和【到位】校验
if (inSsjDevice.getTaskNo() == 0 && inSsjDevice.getDw() == 0) flag = true;
return flag;
}
/**
* 向堆垛机发送【入库】任务
* @param roadSsjDevice
* 入口到位生成wcs本地作业
* @param inSsjDevice
*/
private void sendStackerIn(DeviceSsj roadSsjDevice){
//模拟数据
// roadSsjDevice.setDw(1);
// roadSsjDevice.setTaskNo(85012);
private void generateWcsMydoJob(DeviceSsj inSsjDevice){
//---------------------------入库任务---------------------------
//巷道口输送机到位,且任务号大于1000
if (roadSsjDevice.getDw()==1 && roadSsjDevice.getTaskNo()>1000) {
//如果已经生成wcs任务则不继续执行后续请求操作
//包括请求成功生成作业和wms推送成功的情况
int count = mydoJobService.selectInOrOutMydoJobList(
new MydoJob().builder().trayCode(inSsjDevice.getTrayCode()).build()
).size();
//根据输送机【任务号】查找当前执行的入库任务
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Convert.toLong(roadSsjDevice.getTaskNo()));
if(ObjUtil.isNotNull(mydoJob)){
if (count > 0) return;
//如果任务存在 - 表示该任务已经巷道口输送到位
//更新任务阶段【巷道口入库到位】
if(mydoJob.getExecutionPhase().equals(TASK_EP_SSJ)){
mydoJob.setExecutionPhase(TASK_EP_ROADWAY_SSJ);
mydoJobService.updateMydoJob(mydoJob);
}
// 检查任务属性:【任务已存在】、执行阶段-【巷道口输送机到位】、任务类型-【入库】 → 下发堆垛机执行队列
if (mydoJob.getExecutionPhase().equals(TASK_EP_ROADWAY_SSJ) && Convert.toInt(mydoJob.getInOrOut()) < 20) {
//弯轨堆垛机设备编号使用货位区域编号对应
int devId = Convert.toInt(basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(mydoJob.getCargoSpaceId()).getCargoAreaId());
//检查堆垛机是否在正在执行中/已经有执行队列
List<DdjDeviceExecutionQueue> ddjDeviceExecutionQueues = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueListByRwlx(DDJ_RWLX_3, devId);
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(mydoJob.getCargoSpaceId());
List<Integer> pclList = roadwayMap.get(roadSsjDevice.getDeviceCode());
//生成堆垛机执行队列
if (CollUtil.isEmpty(ddjDeviceExecutionQueues) && ObjUtil.isNotNull(basCargoSpace) && CollUtil.isNotEmpty(pclList)) {
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueue.setUuid(IdUtil.simpleUUID());
ddjDeviceExecutionQueue.setRwh(Convert.toLong(mydoJob.getTaskNo()));
ddjDeviceExecutionQueue.setDevName(mydoJob.getRoadwayId());
ddjDeviceExecutionQueue.setDevId(devId);
ddjDeviceExecutionQueue.setRwzt(0);
ddjDeviceExecutionQueue.setYph(pclList.get(0));
ddjDeviceExecutionQueue.setYlh(pclList.get(1));
ddjDeviceExecutionQueue.setYch(pclList.get(2));
ddjDeviceExecutionQueue.setMbph(Convert.toInt(basCargoSpace.getThePlatoon()));
ddjDeviceExecutionQueue.setMblh(Convert.toInt(basCargoSpace.getTheColumn()));
ddjDeviceExecutionQueue.setMbch(Convert.toInt(basCargoSpace.getTheFloor()));
ddjDeviceExecutionQueue.setDdjxf("0");
ddjDeviceExecutionQueue.setMlfs(5);
ddjDeviceExecutionQueue.setSpare1(mydoJob.getTraySize());//货物高度
ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date()));
ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_3);
ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
if (ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(ddjDeviceExecutionQueue).size() > 0){
//下发后更新任务阶段
mydoJob.setExecutionPhase(TASK_EP_DDJ);
mydoJobService.updateMydoJob(mydoJob);
}
}
}
}
//-----------------警告校验:条码已有库存-----------------
BasCargoSpace cargoSpace = new BasCargoSpace();
cargoSpace.setTrayCode(inSsjDevice.getTrayCode());
if (!basCargoSpaceService.selectBasCargoSpaceList(cargoSpace).isEmpty()) {
log.warn("【警告】该托盘号已有库存,托盘条码:{}",inSsjDevice.getTrayCode());
}
int trayType = mydoJobService.getTraytypeByTrayCode(inSsjDevice.getTrayCode());
//生成的任务初始化
MydoJob mydoJob = new MydoJob().builder()
// .jobId(result.getJobId())
.taskNo(mydoJobService.getTaskNo("2"))//如果需要用wms下发的任务号作为wcs的任务号使用
.status(TASK_STATUS_CREATED)
.trayCode(inSsjDevice.getTrayCode())
// .cargoSpaceId(result.getCargoSpaceId())
// .wmsTaskNo(mydoJobService.getTaskNo("1"))
.traySize(inSsjDevice.getHeight())
.inOrOut("1")
.roadwayId(String.valueOf(ConvType.CONV_ROAD_ROADWAY.get(inSsjDevice.getDeviceCode())))//获取货位表货位对应的巷道号
.entranceId(inSsjDevice.getDeviceCode())
.executionPhase(TASK_EP_CREATED)
.faultFlag("0")
.traySize(trayType)
.priority(10)
.build();
//如果还没有这个条码的wcs任务 - 生成一条任务
List<MydoJob> jobs = mydoJobService.selectMydoJobList(
new MydoJob().builder().trayCode(inSsjDevice.getTrayCode()).build()
);
if (jobs.isEmpty()) {
mydoJobService.insertMydoJob(mydoJob);
log.info("【生成入库】本地生成wcs作业成功,wcs任务号:{},托盘条码:{}", mydoJob.getTaskNo(), mydoJob.getTrayCode());
}
}
/**
* 更新入库任务阶段
* @param inSsjDevice
*/
private void updateMydoJob(DeviceSsj inSsjDevice) {
//-------------------------------------------常规入库-------------------------------------------
//检查是否有已经创建成功的任务(请求成功的入库任务) - 更新到下一个执行阶段
MydoJob mydoJobStockin = new MydoJob().builder()
.trayCode(inSsjDevice.getTrayCode())
.status(TASK_STATUS_CREATED)
.build();
if (mydoJobService.selectMydoJobList(mydoJobStockin).isEmpty()) return;
//如果已经生成入库任务 - 向输送机下发任务号
mydoJobStockin = mydoJobService.selectMydoJobList(mydoJobStockin).get(0);
//输送机去向值【1】
int i = writeToSsj(inSsjDevice.getPlcDbWriteAddress(), mydoJobStockin.getTaskNo(), 1, 1);
if (i == 1) {
//写入成功则更新执行阶段
mydoJobStockin.setStatus(TASK_STATUS_RUNNING);
mydoJobStockin.setExecutionPhase(TASK_EP_ROADWAY_SSJ);
// mydoJobStockin.setEntranceId(inSsjDevice.getDeviceCode());
mydoJobStockin.setStartTime(DateUtil.formatDateTime(DateUtil.date()));
mydoJobService.updateMydoJob(mydoJobStockin);
log.info("【更新状态】巷道输送机{}下发成功,任务号:{},等待堆垛机取货", inSsjDevice.getDeviceCode(), mydoJobStockin.getTaskNo());
}else{
log.info("【更新状态】巷道输送机{}下发失败,任务号:{},等待重试中...", inSsjDevice.getDeviceCode(), mydoJobStockin.getTaskNo());
}
}
/**
* 向堆垛机发送【出库】任务
* @param roadSsjDevice
@@ -214,59 +310,57 @@ public class RoadConvThread implements Runnable {
private void sendStackerOut(DeviceSsj roadSsjDevice){
//---------------------------出库任务---------------------------
//检查巷道口输送机是否空闲
if(roadSsjDevice.getKx()==1 && roadSsjDevice.getTaskNo() == 0){
if(roadSsjDevice.getKx() == 1 && roadSsjDevice.getTaskNo() == 0){
//检查是否有入口是1#巷道的出库任务
String exitId = ROADWAY1_EXIT;
MydoJob job = mydoJobService.selectMydoJobByExitId(exitId);
String exitId = roadSsjDevice.getDeviceCode();
if(job == null){
//检查是否有出库任务
MydoJob mydoJob = mydoJobService.selectMydoJobByExitId(exitId);
if (ObjUtil.isNotNull(mydoJob)) {
//如果有出库任务 - 检查货位编码是否合法
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(mydoJob.getCargoSpaceId());
if (ObjUtil.isNull(basCargoSpace)) {
log.error("【任务异常】货位不存在 cargoSpaceId{}", mydoJob.getCargoSpaceId());
} else {
//生成队列
List<DdjDeviceExecutionQueue> list = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueListByRwlx(DDJ_RWLX_2, Convert.toInt(mydoJob.getRoadwayId()));
List<Integer> pclList = roadwayMap.get(roadSsjDevice.getDeviceCode());
if (CollUtil.isEmpty(list) && CollUtil.isNotEmpty(pclList)) {
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueue.setUuid(IdUtil.simpleUUID());
ddjDeviceExecutionQueue.setRwh(Convert.toLong(mydoJob.getTaskNo()));
ddjDeviceExecutionQueue.setDevName(mydoJob.getRoadwayId());
ddjDeviceExecutionQueue.setDevId(Convert.toInt(mydoJob.getRoadwayId()));
ddjDeviceExecutionQueue.setRwzt(0);
ddjDeviceExecutionQueue.setYph(Convert.toInt(basCargoSpace.getThePlatoon()));
ddjDeviceExecutionQueue.setYlh(Convert.toInt(basCargoSpace.getTheColumn()));
ddjDeviceExecutionQueue.setYch(Convert.toInt(basCargoSpace.getTheFloor()));
ddjDeviceExecutionQueue.setMbph(pclList.get(0));
ddjDeviceExecutionQueue.setMblh(pclList.get(1));
ddjDeviceExecutionQueue.setMbch(pclList.get(2));
ddjDeviceExecutionQueue.setDdjxf("0");
ddjDeviceExecutionQueue.setMlfs(5);
ddjDeviceExecutionQueue.setSpare1(mydoJob.getTraySize());//货物高度
ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date()));
ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_2);
ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
//修改作业状态
mydoJob.setStatus(TASK_STATUS_RUNNING);
mydoJob.setExecutionPhase(TASK_EP_DDJ);
mydoJob.setStartTime(DateUtil.formatDateTime(DateUtil.date()));
mydoJobService.updateMydoJob(mydoJob);
}
//检查是否有出库任务
MydoJob mydoJob = mydoJobService.selectMydoJobByExitId(exitId);
if (ObjUtil.isNotNull(mydoJob)) {
//如果有出库任务 - 检查货位编码是否合法
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(mydoJob.getCargoSpaceId());
if (ObjUtil.isNull(basCargoSpace)) {
log.error("【任务异常】货位不存在 cargoSpaceId{}", mydoJob.getCargoSpaceId());
} else {
//生成队列
List<DdjDeviceExecutionQueue> list = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(
new DdjDeviceExecutionQueue().builder().devId(Convert.toInt(mydoJob.getRoadwayId())).build()
);
List<Integer> pclList = roadwayMap.get(roadSsjDevice.getDeviceCode());
if (CollUtil.isEmpty(list) && CollUtil.isNotEmpty(pclList)) {
DdjDeviceExecutionQueue ddjDeviceExecutionQueue = new DdjDeviceExecutionQueue();
ddjDeviceExecutionQueue.setUuid(IdUtil.simpleUUID());
ddjDeviceExecutionQueue.setRwh(Convert.toLong(mydoJob.getTaskNo()));
ddjDeviceExecutionQueue.setDevName(mydoJob.getRoadwayId());
ddjDeviceExecutionQueue.setDevId(Convert.toInt(mydoJob.getRoadwayId()));
ddjDeviceExecutionQueue.setRwzt(0);
ddjDeviceExecutionQueue.setYph(Convert.toInt(basCargoSpace.getThePlatoon()));
ddjDeviceExecutionQueue.setYlh(Convert.toInt(basCargoSpace.getTheColumn()));
ddjDeviceExecutionQueue.setYch(Convert.toInt(basCargoSpace.getTheFloor()));
ddjDeviceExecutionQueue.setMbph(pclList.get(0));
ddjDeviceExecutionQueue.setMblh(pclList.get(1));
ddjDeviceExecutionQueue.setMbch(pclList.get(2));
ddjDeviceExecutionQueue.setDdjxf("0");
ddjDeviceExecutionQueue.setMlfs(5);
ddjDeviceExecutionQueue.setSpare1(mydoJob.getTraySize().toString());//货物高度
ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date()));
// ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_2);
ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
//修改作业状态
mydoJob.setStatus(TASK_STATUS_RUNNING);
mydoJob.setExecutionPhase(TASK_EP_DDJ);
mydoJob.setStartTime(DateUtil.formatDateTime(DateUtil.date()));
mydoJobService.updateMydoJob(mydoJob);
}
}
}else{
log.info("【出库警告】当前出口"+ exitId +"存在入库任务,无法出库!");
// log.info("【出库警告】当前出口"+ exitId +"存在入库任务,无法出库!");
}
}
}
}