优化调整
This commit is contained in:
@@ -31,7 +31,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import static com.ruoyi.common.TaskExceptionType.TASK_EXCEPTION_STOCKIN_OCCUPIED;
|
||||
import static com.ruoyi.common.TaskExceptionType.TASK_EXCEPTION_STOCKOUT_EMPTY;
|
||||
import static com.ruoyi.common.TaskStatusCode.TASK_EP_DDJ_FINISH;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@@ -114,9 +114,12 @@ public class DdjThread implements Runnable {
|
||||
|
||||
//满足上述条件,表示该任务已完成-执行任务回传
|
||||
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());
|
||||
log.info("【堆垛机入库】堆垛机:"+ddj.getId()+"任务完成,任务号:"+ddj.getRwh());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +174,7 @@ public class DdjThread implements Runnable {
|
||||
MydoJob wmsJob = new MydoJob();
|
||||
wmsJob.setInOrOut(mydoJobReAssign.getTaskCode());
|
||||
if (mydoJobService.selectMydoJobList(wmsJob).size() == 0) {
|
||||
log.warn("该任务不存在,任务号:{}", mydoJobReAssign.getTaskCode());
|
||||
log.warn("【响应异常】该任务不存在,任务号:{}", mydoJobReAssign.getTaskCode());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -257,9 +260,9 @@ public class DdjThread implements Runnable {
|
||||
ddjDeviceExecutionQueueService.updateDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
|
||||
mydoJob.setFaultFlag("0");
|
||||
mydoJobService.updateMydoJob(mydoJob);
|
||||
log.info("堆垛机放货目标有货,重分货位下发任务成功 rwh:{}", rwh);
|
||||
log.info("【入库异常】堆垛机放货目标有货,重分货位下发任务成功 rwh:{}", rwh);
|
||||
} else {
|
||||
log.error("堆垛机放货目标有货,重分货位下发任务失败!!!!!!!");
|
||||
log.error("【出库异常】堆垛机放货目标有货,重分货位下发任务失败!!!!!!!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -275,7 +278,7 @@ public class DdjThread implements Runnable {
|
||||
ddjDeviceExecutionQueueRunningParam.setDevId(ddj.getId());
|
||||
List<DdjDeviceExecutionQueue> ddjDeviceExecutionRunningQueues = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList(ddjDeviceExecutionQueueRunningParam);
|
||||
if (CollUtil.isNotEmpty(ddjDeviceExecutionRunningQueues)) {
|
||||
log.error("堆垛机有正在执行的任务 {}" , ddjDeviceExecutionRunningQueues.get(0).getRwh());
|
||||
log.error("【提示】堆垛机有正在执行的任务 {}" , ddjDeviceExecutionRunningQueues.get(0).getRwh());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -294,9 +297,9 @@ public class DdjThread implements Runnable {
|
||||
ddjDeviceExecutionQueue.setXfsj(DateUtil.formatDateTime(DateUtil.date()));
|
||||
ddjDeviceExecutionQueue.setDdjxf("1");
|
||||
ddjDeviceExecutionQueueService.updateDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
|
||||
log.info("堆垛机下发任务成功 rwh:{}", ddjDeviceExecutionQueue.getRwh());
|
||||
log.info("【执行成功】堆垛机下发任务成功 rwh:{}", ddjDeviceExecutionQueue.getRwh());
|
||||
} else {
|
||||
log.error("堆垛机下发任务失败!!!!!!!");
|
||||
log.error("【执行异常】堆垛机下发任务失败!!!!!!!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -339,9 +342,9 @@ public class DdjThread implements Runnable {
|
||||
int mbch = Convert.toInt(queue.getMbch());
|
||||
int mlfs = 5;
|
||||
int xfwc = 1;
|
||||
int hwlx = Convert.toInt(queue.getSpare1());
|
||||
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 rwlx = Convert.toInt(queue.getSpare1());
|
||||
int jym = Tools.getJYM(taskNo, yph, ylh, ych, mbph, mblh, mbch, mlfs, rwlx);
|
||||
byte[] sendData = Tools.sendDataToDevice(taskNo, null, yph, ylh, ych, mbph, mblh, mbch, mlfs, rwlx, xfwc, jym);
|
||||
if (devId==1){
|
||||
return PlcDdj1Read.WriteToDDJ("DB61.0", sendData);
|
||||
}else {
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.ruoyi.schedule.scheduleTask.ssj;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.ruoyi.api.domain.wcs2wms.stockin.StockinReceive;
|
||||
import com.ruoyi.api.service.IApiService;
|
||||
@@ -17,20 +16,23 @@ import com.ruoyi.job.domain.JobCallBack;
|
||||
import com.ruoyi.job.domain.MydoJob;
|
||||
import com.ruoyi.job.service.IJobCallBackService;
|
||||
import com.ruoyi.job.service.IMydoJobService;
|
||||
import com.ruoyi.queue.agv.domain.AgvQueue;
|
||||
import com.ruoyi.queue.agv.service.IAgvQueueService;
|
||||
import com.ruoyi.schedule.plcRead.ssj.PlcSsjRead;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.ruoyi.common.TaskStatusCode.*;
|
||||
import static com.ruoyi.common.WmsTaskTypeCode.WMS_TASK_TYPE_STOCKIN;
|
||||
import static com.ruoyi.common.WmsTaskTypeCode.WMS_TASK_TYPE_STOCKOUT;
|
||||
import static com.ruoyi.schedule.plcRead.ssj.PlcSsjRead.writeToSsj;
|
||||
import static com.ruoyi.schedule.plcRead.ssj.PlcSsjRead.writeToSsjQH;
|
||||
|
||||
/**
|
||||
* 出入口输送线线程
|
||||
@@ -137,6 +139,7 @@ public class PortConvThread implements Runnable {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 请求wms获取wcs任务参数
|
||||
* @param inSsjDevice
|
||||
@@ -152,12 +155,12 @@ public class PortConvThread implements Runnable {
|
||||
|
||||
//请求参数
|
||||
HashMap<String, Object> paramMap = new HashMap<>();
|
||||
paramMap.put("taskTypeCode", "inBound");//任务类型编号
|
||||
paramMap.put("taskTypeCode", WMS_TASK_TYPE_STOCKIN);//todo wms自定义的任务类型编号
|
||||
paramMap.put("reqCode", UUID.randomUUID().toString());//请求码
|
||||
paramMap.put("cntCode", inSsjDevice.getTrayCode());//容器编号
|
||||
String height = inSsjDevice.getHeight();
|
||||
String weight = inSsjDevice.getWeight();
|
||||
paramMap.put("weight", weight);//重量
|
||||
// String weight = inSsjDevice.getWeight();//todo 需要直读重量或从plc读值?
|
||||
paramMap.put("weight", getWeight(MOXA_IP, MOXA_PORT, SO_TIMEOUT_MS));//重量
|
||||
paramMap.put("altimetry", height);//高度
|
||||
String errorMessage = "";
|
||||
|
||||
@@ -221,14 +224,14 @@ public class PortConvThread implements Runnable {
|
||||
mydoJob.setWmsTaskNo(result.getTaskCode());
|
||||
mydoJob.setJobId(mydoJobService.getJobId("RK"));
|
||||
mydoJob.setTaskNo(mydoJobService.getTaskNo("1"));
|
||||
// mydoJob.setTaskNo(result.getTaskCode());//todo 确定是否用获取的任务号作为wcs的任务号
|
||||
// mydoJob.setTaskNo(result.getTaskCode());//需要确定是否用获取的任务号作为wcs的任务号
|
||||
|
||||
//校验:wms分配的货位(排列层)是否合法
|
||||
if (result.getSiteCode() == null || result.getSiteCode().isEmpty()) {
|
||||
log.info("【请求参数异常】分配货位:null,无法生成作业,托盘条码:{}",inSsjDevice.getTrayCode());
|
||||
return;
|
||||
}else {
|
||||
mydoJob.setRoadwayId(basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(mydoJob.getCargoSpaceId()).getRoadwayId());
|
||||
// mydoJob.setRoadwayId(basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(mydoJob.getCargoSpaceId()).getRoadwayId());
|
||||
}
|
||||
|
||||
mydoJob.setStatus("1");
|
||||
@@ -291,30 +294,87 @@ public class PortConvThread implements Runnable {
|
||||
* @param inSsjDevice
|
||||
*/
|
||||
private void finishStockoutMydoJob(DeviceSsj inSsjDevice){
|
||||
//出库到位
|
||||
//出库到位
|
||||
if (inSsjDevice.getDw() == 1 && inSsjDevice.getTaskNo() > 0) {
|
||||
//查询该出库任务
|
||||
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Convert.toLong(inSsjDevice.getTaskNo()));
|
||||
if (mydoJob != null && Integer.parseInt(mydoJob.getInOrOut()) > 20) {
|
||||
log.info("【出库到位】设备:{},位置:{},任务号:{},出库到位", "输送线:", inSsjDevice.getDeviceCode(), mydoJob.getTaskNo());
|
||||
mydoJobService.insertHistory(mydoJob.getJobId());
|
||||
mydoJobService.deleteMydoJobByJobId(mydoJob.getJobId());
|
||||
JobCallBack jobCallBack = new JobCallBack();
|
||||
jobCallBack.setType("2");
|
||||
jobCallBack.setMydojobId(mydoJob.getJobId());
|
||||
jobCallBack.setStatus("0");
|
||||
jobCallBack.setTaskNo(Convert.toLong(mydoJob.getTaskNo()));
|
||||
jobCallBack.setCreateTime(new Date());
|
||||
jobCallBack.setTaskTypeCode("");//todo ???
|
||||
jobCallBack.setReqCode(UUID.randomUUID().toString().replace("-", ""));
|
||||
jobCallBack.setTaskCode(mydoJob.getWmsTaskNo());
|
||||
// jobCallBack.setSpare1("0");
|
||||
jobCallBackService.insertJobCallBack(jobCallBack);
|
||||
mydoJob.setExecutionPhase(TASK_EP_SSJ_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 getWeight(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) {
|
||||
|
||||
@@ -23,7 +23,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import java.util.*;
|
||||
|
||||
import static com.ruoyi.common.TaskStatusCode.*;
|
||||
import static com.ruoyi.common.TaskType.DDJ_RWLX_1;
|
||||
import static com.ruoyi.common.TaskType.*;
|
||||
|
||||
/**
|
||||
* 巷道口输送机(堆垛机取放位)线程 检测当前巷道有没有入库作业,没有作业,生成堆垛机出库队列
|
||||
@@ -106,30 +106,29 @@ public class RoadConvThread implements Runnable {
|
||||
*/
|
||||
private void sendStackerIn(DeviceSsj roadSsjDevice){
|
||||
//模拟数据
|
||||
roadSsjDevice.setDw(1);
|
||||
roadSsjDevice.setTaskNo(85012);
|
||||
// roadSsjDevice.setDw(1);
|
||||
// roadSsjDevice.setTaskNo(85012);
|
||||
|
||||
//---------------------------入库任务---------------------------
|
||||
//巷道口输送机到位,且任务号大于1000
|
||||
if (roadSsjDevice.getDw()==1 && roadSsjDevice.getTaskNo()>1000) {
|
||||
|
||||
//查找当前执行的入库任务
|
||||
//根据输送机【任务号】查找当前执行的入库任务
|
||||
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Convert.toLong(roadSsjDevice.getTaskNo()));
|
||||
if(ObjUtil.isNotNull(mydoJob)){
|
||||
|
||||
//更新任务阶段: 入口输送机 → 巷道口入库到位
|
||||
//如果任务存在 - 表示该任务已经巷道口输送到位
|
||||
//更新任务阶段【巷道口入库到位】
|
||||
if(mydoJob.getExecutionPhase().equals(TASK_EP_SSJ)){
|
||||
mydoJob.setExecutionPhase(TASK_EP_ROADWAY_SSJ);
|
||||
mydoJobService.updateMydoJob(mydoJob);
|
||||
}
|
||||
|
||||
// 检查任务属性:【任务已存在】、执行阶段-【巷道口输送机到位】、任务类型-【入库】
|
||||
// 下发堆垛机执行队列
|
||||
if (ObjUtil.isNotNull(mydoJob)
|
||||
&& mydoJob.getExecutionPhase().equals(TASK_EP_ROADWAY_SSJ)
|
||||
&& Convert.toInt(mydoJob.getInOrOut()) < 20) {
|
||||
// 检查任务属性:【任务已存在】、执行阶段-【巷道口输送机到位】、任务类型-【入库】 → 下发堆垛机执行队列
|
||||
if (mydoJob.getExecutionPhase().equals(TASK_EP_ROADWAY_SSJ) && Convert.toInt(mydoJob.getInOrOut()) < 20) {
|
||||
|
||||
//检查堆垛机是否在正在执行中
|
||||
List<DdjDeviceExecutionQueue> ddjDeviceExecutionQueues = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueListByRwlx(DDJ_RWLX_1, Convert.toInt(mydoJob.getRoadwayId()));
|
||||
//检查堆垛机是否在正在执行中/已经有执行队列
|
||||
List<DdjDeviceExecutionQueue> ddjDeviceExecutionQueues = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueListByRwlx(DDJ_RWLX_3, Convert.toInt(mydoJob.getRoadwayId()));
|
||||
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(mydoJob.getCargoSpaceId());
|
||||
List<Integer> pclList = roadwayMap.get(roadSsjDevice.getDeviceCode());
|
||||
|
||||
@@ -149,9 +148,9 @@ public class RoadConvThread implements Runnable {
|
||||
ddjDeviceExecutionQueue.setMbch(Convert.toInt(basCargoSpace.getTheFloor()));
|
||||
ddjDeviceExecutionQueue.setDdjxf("0");
|
||||
ddjDeviceExecutionQueue.setMlfs(5);
|
||||
ddjDeviceExecutionQueue.setSpare1(mydoJob.getTraySize());
|
||||
// ddjDeviceExecutionQueue.setSpare1(mydoJob.getTraySize());
|
||||
ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date()));
|
||||
ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_1);
|
||||
ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_3);
|
||||
ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
|
||||
|
||||
//下发后更新任务阶段
|
||||
@@ -188,7 +187,7 @@ public class RoadConvThread implements Runnable {
|
||||
log.error("【任务异常】货位不存在 cargoSpaceId{}", mydoJob.getCargoSpaceId());
|
||||
} else {
|
||||
//生成队列
|
||||
List<DdjDeviceExecutionQueue> list = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueListByRwlx(DDJ_RWLX_1, Convert.toInt(mydoJob.getRoadwayId()));
|
||||
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();
|
||||
@@ -207,7 +206,7 @@ public class RoadConvThread implements Runnable {
|
||||
ddjDeviceExecutionQueue.setMlfs(5);
|
||||
ddjDeviceExecutionQueue.setSpare1(mydoJob.getTraySize());
|
||||
ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date()));
|
||||
ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_1);
|
||||
ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_2);
|
||||
ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue);
|
||||
|
||||
//修改作业状态
|
||||
|
||||
Reference in New Issue
Block a user