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.exception.CoolException;
|
import com.zy.asrs.domain.enums.TaskStatusType;
|
import com.zy.asrs.entity.*;
|
import com.zy.asrs.mapper.*;
|
import com.zy.asrs.service.*;
|
import com.zy.common.utils.HttpHandler;
|
import com.zy.core.DevpThread;
|
import com.zy.core.cache.MessageQueue;
|
import com.zy.core.cache.SlaveConnection;
|
import com.zy.core.enums.*;
|
import com.zy.core.model.CrnSlave;
|
import com.zy.core.model.Task;
|
import com.zy.core.model.protocol.StaProtocol;
|
import com.zy.core.properties.SlaveProperties;
|
import com.zy.core.thread.SiemensDevpThread;
|
import com.zy.system.entity.Config;
|
import com.zy.system.service.ConfigService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.io.IOException;
|
import java.util.*;
|
|
/**
|
* 立体仓库WCS系统主流程业务
|
*/
|
@Slf4j
|
@Service("mainService")
|
@Transactional
|
public class MainServiceImpl {
|
|
public static final long COMMAND_TIMEOUT = 5 * 1000;
|
|
@Autowired
|
private SlaveProperties slaveProperties;
|
@Autowired
|
private LocMastService locMastService;
|
@Autowired
|
private BasDevpService basDevpService;
|
@Autowired
|
private TaskWrkMapper taskWrkMapper;
|
@Autowired
|
private TaskWrkService taskWrkService;
|
@Autowired
|
private ConfigService configService;
|
@Autowired
|
private StaDescMapper staDescMapper;
|
@Autowired
|
private CommandInfoService commandInfoService;
|
@Autowired
|
private ApiLogService apiLogService;
|
@Value("${wcs.urlWcs}")
|
private String wcsUrl;
|
@Value("${wcs.inboundTaskApplyPathWcs}")
|
private String wcsInboundTaskApplyPath;
|
|
/**
|
* 堆垛机站出库到出库站
|
*/
|
public synchronized void crnStnToOutStn() {
|
for (CrnSlave crnSlave : slaveProperties.getCrn()) {
|
// 遍历堆垛机出库站
|
for (CrnSlave.CrnStn crnStn : crnSlave.getCrnOutStn()) {
|
List<StaDesc> staDescs = staDescMapper.selectList(new EntityWrapper<StaDesc>().eq("crn_no", crnSlave.getId()).eq("crn_stn", crnStn.getStaNo()));
|
for (StaDesc staDesc : staDescs) {
|
try {
|
// 获取堆垛机出库站信息
|
DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId());
|
StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo());
|
if (staProtocol == null) {
|
continue;
|
} else {
|
staProtocol = staProtocol.clone();
|
}
|
if (staProtocol.isAutoing() && staProtocol.isLoading() && (staProtocol.getWorkNo() == 0 || staProtocol.getStaNo() == 0)) {
|
// 查询工作档
|
TaskWrk taskWrk = taskWrkMapper.selectCrnStaWorking(crnSlave.getId(), staDesc.getStnNo().toString());
|
if (taskWrk == null) {
|
continue;
|
}
|
log.info("下发输送线任务:taskWrk:" + JSON.toJSONString(taskWrk));
|
// R r = siteController.siteDetlUpdate(Integer.valueOf(taskWrk.getTargetPoint()), taskWrk.getWrkNo().shortValue(), (short) 0, "Y", false, false);
|
staProtocol.setWorkNo(taskWrk.getWrkNo().shortValue());
|
staProtocol.setStaNo(staDesc.getStnNo().shortValue());
|
boolean offer = false;
|
try {
|
offer = MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocol));
|
} catch (Exception e) {
|
log.error("下发输送线任务失败:异常:" + e);
|
log.error("下发输送线任务失败:异常:offer:" + offer);
|
}
|
// JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(r));
|
if (offer) {
|
log.info("下发输送线任务成功:taskWrk:" + JSON.toJSONString(taskWrk));
|
taskWrk.setStatus(5);
|
taskWrk.setWrkSts(14);
|
taskWrkService.updateById(taskWrk);
|
|
} else {
|
log.error("下发输送线任务失败:taskWrk:" + JSON.toJSONString(taskWrk));
|
// log.error("下发输送线任务失败:异常信息:"+JSON.toJSONString(r));
|
}
|
}
|
} catch (Exception e) {
|
log.error("出库到出库站异常:异常信息:" + e);
|
}
|
}
|
|
}
|
}
|
}
|
|
/**
|
* 入出库 ===>> 调用RCS进行入出库
|
*/
|
public synchronized void crnIoExecute() throws IOException {
|
for (CrnSlave crn : slaveProperties.getCrn()) {
|
this.crnStnToLoc(crn); // 入库
|
this.locToCrnStn(crn); // 出库
|
// 库位移转
|
// this.locToLoc(crn, crnProtocol);
|
}
|
}
|
|
/**
|
* 入库 ===>> 堆垛机站到库位
|
*/
|
public synchronized void crnStnToLoc(CrnSlave slave) throws IOException {
|
for (CrnSlave.CrnStn crnStn : slave.getCrnInStn()) {
|
List<StaDesc> staDescs = staDescMapper.selectList(new EntityWrapper<StaDesc>().eq("crn_no", slave.getId()).eq("crn_stn", crnStn.getStaNo()));
|
for (StaDesc staDesc : staDescs) {
|
boolean flag = false;
|
// 获取堆垛机入库站信息
|
DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId());
|
StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo());
|
if (staProtocol == null) {
|
continue;
|
} else {
|
staProtocol = staProtocol.clone();
|
}
|
// 查询站点详细信息
|
BasDevp staDetl = basDevpService.selectById(crnStn.getStaNo());
|
if (staDetl == null) {
|
log.error("入库 ===>> 堆垛机站点在数据库不存在, 站点编号={}", crnStn.getStaNo());
|
continue;
|
}
|
if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.getWorkNo() > 0 && staProtocol.isInEnable()
|
&& staDetl.getCanining() != null && staDetl.getCanining().equals("Y")) {
|
flag = true;
|
}
|
if (!flag) {
|
continue;
|
}
|
|
// 获取工作状态为2(设备上走)的入库工作档
|
TaskWrk taskWrk = taskWrkMapper.selectPakIn(slave.getId(), staProtocol.getWorkNo().intValue(), staDesc.getStnNo().toString());
|
if (null == taskWrk) {
|
continue;
|
}
|
|
String mbz=taskWrk.getTargetPoint().substring(5);
|
|
HashMap<String, Object> hashMap = new HashMap<>();
|
hashMap.put("taskNo",taskWrk.getTaskNo());//wms任务号
|
hashMap.put("sourceStaNo",staDetl.getDevNo());//源站点
|
hashMap.put("staNo",Integer.parseInt(mbz)+"");//目标站
|
hashMap.put("locNo",taskWrk.getTargetPoint());//目标库位
|
String response = "";
|
Boolean bool = false;
|
try {
|
//开始上报,出库任务开始时,WCS回调WMS
|
response = new HttpHandler.Builder()
|
.setUri(wcsUrl)
|
.setPath(wcsInboundTaskApplyPath)
|
.setJson(JSON.toJSONString(hashMap))
|
.build()
|
.doPost();
|
JSONObject jsonObject = JSON.parseObject(response);
|
|
if(jsonObject.get("code").equals(200)){
|
bool = true;
|
taskWrk.setStatus(TaskStatusType.DISTRIBUTE.id);//派发状态
|
taskWrk.setAssignTime(new Date());//派发时间
|
taskWrk.setWrkSts(3);//工作状态 3.成功下发入库任务给RCS
|
taskWrk.setCrnNo(staDesc.getCrnNo());//堆垛机号
|
taskWrk.setModiTime(new Date());
|
taskWrk.setModiUser(9988L);
|
}
|
} catch (Exception e) {
|
}finally {
|
apiLogService.save("wcs派发入库任务给RCS"
|
, wcsUrl + wcsInboundTaskApplyPath
|
, null
|
, "127.0.0.1"
|
, JSON.toJSONString(hashMap)
|
, response
|
, bool
|
);
|
}
|
}
|
}
|
}
|
|
/**
|
* 出库 ===>> 库位到堆垛机站
|
* 2022-06-09 TQS修改,查询工作档LIST,遍历下发,防止第一个任务堵塞出库
|
*/
|
public synchronized void locToCrnStn(CrnSlave slave) {
|
List<TaskWrk> taskWrksInitial = taskWrkMapper.selectPakOut(slave.getId(), null);
|
if (taskWrksInitial.size() == 0) {
|
return;
|
}
|
for (CrnSlave.CrnStn crnStn : slave.getCrnOutStn()) {
|
List<StaDesc> staDescs = staDescMapper.selectList(new EntityWrapper<StaDesc>().eq("crn_no", slave.getId()).eq("crn_stn", crnStn.getStaNo()));
|
for (StaDesc staDesc : staDescs) {
|
// 获取工作状态为11(生成出库ID)的出库工作档
|
List<TaskWrk> taskWrks = taskWrkMapper.selectPakOut(slave.getId(), staDesc.getStnNo().toString());
|
for (TaskWrk taskWrk : taskWrks) {
|
if (taskWrk == null) {
|
continue;
|
}
|
// 工作档状态判断
|
if (taskWrk.getIoType() != 2 || taskWrk.getTargetPoint() == null || taskWrk.getStartPoint() == null) {
|
log.error("查询工作档数据不符合条件--入出类型/站点, 工作号={},源库位={},入出类型={}", taskWrk.getWrkNo(), taskWrk.getStartPoint(), taskWrk.getIoType());
|
continue;
|
}
|
|
LocMast locMast = locMastService.selectByLocNo(taskWrk.getStartPoint());
|
//判断其库位是否为深库位,如果为深库位找其浅库位是都有货
|
//预留
|
|
|
// 获取堆垛机出库站信息
|
SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId());
|
StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo());
|
if (staProtocol == null) {
|
break;
|
} else {
|
staProtocol = staProtocol.clone();
|
}
|
|
// 查询站点详细信息
|
BasDevp staDetl = basDevpService.selectById(crnStn.getStaNo());
|
if (staDetl == null) {
|
log.error("出库 ===>> 堆垛机站点在数据库不存在, 站点编号={}", crnStn.getStaNo());
|
break;
|
}
|
|
// 判断堆垛机出库站状态
|
if (staProtocol.isAutoing() && !staProtocol.isLoading() && staDetl.getCanouting() != null && staDetl.getCanouting().equals("Y")
|
&& staProtocol.getWorkNo() == 0 && staProtocol.isOutEnable()) {
|
// 命令下发区 --------------------------------------------------------------------------
|
|
// 已经存在吊车执行任务时,则过滤
|
if (taskWrkMapper.selectCrnWorking(slave.getId()) != null) {
|
break;
|
}
|
|
try {
|
// 修改工作档状态 11.生成出库ID => 12.吊车出库中
|
Date now = new Date();
|
taskWrk.setWrkSts(12);
|
taskWrk.setModiTime(now);
|
if (taskWrkMapper.updateById(taskWrk) == 0) {
|
log.error("修改工作档状态 11.生成出库ID => 12.吊车出库中 失败!!,工作号={}", taskWrk.getWrkNo());
|
}
|
} catch (Exception e) {
|
log.error("修改工作档状态 11.生成出库ID => 12.吊车出库中 失败!!,工作号={}", taskWrk.getWrkNo());
|
log.error("修改工作档状态 11.生成出库ID => 12.吊车出库中 失败!!,异常:" + e);
|
}
|
// try {
|
// HashMap<String, Object> headParam = new HashMap<>();
|
// headParam.put("taskNo", taskWrk.getTaskNo());
|
// headParam.put("status", taskWrk.getStatus());
|
// headParam.put("ioType", taskWrk.getIoType());
|
// headParam.put("barcode", taskWrk.getBarcode());
|
// String response;
|
// response = new HttpHandler.Builder()
|
// // .setHeaders(headParam)
|
// .setUri(wmsUrl)
|
// .setPath(taskStatusFeedbackPath)
|
// .setJson(JSON.toJSONString(headParam))
|
// .build()
|
// .doPost();
|
// JSONObject jsonObject = JSON.parseObject(response);
|
// apiLogService.save("wcs派发出库任务上报wms"
|
// , wmsUrl + taskStatusFeedbackPath
|
// , null
|
// , "127.0.0.1"
|
// , JSON.toJSONString(headParam)
|
// , response
|
// , true
|
// );
|
// } catch (Exception e) {
|
// log.error("wcs派发出库任务上报wms失败", JSON.toJSONString(taskWrk));
|
//// throw new CoolException("wcs派发入库任务上报wms失败");
|
// }
|
|
}
|
}
|
}
|
}
|
}
|
|
//自动派发任务
|
public synchronized void autoDistribute() {
|
Config config = configService.selectByCode("autoDistribute");
|
if (config == null) {
|
return;
|
}
|
|
if (config.getValue().equals("false")) {//判断是否开启自动派发任务
|
return;
|
}
|
|
for (TaskWrk taskWrk : taskWrkService.selectReceive()) {
|
|
try {
|
taskWrkService.distribute(taskWrk.getTaskNo(), 9527L);
|
} catch (CoolException e) {
|
log.info(e.getMessage());
|
}
|
}
|
}
|
|
//agv取放货任务完成
|
public synchronized void autoCompleteAGV() {
|
List<BasDevp> basDevps = basDevpService.selectList(new EntityWrapper<>());
|
try {
|
Thread.sleep(500);
|
} catch (Exception e) {
|
|
}
|
|
for (BasDevp basDevp : basDevps) {
|
DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, 1);
|
StaProtocol staProtocol = devpThread.getStation().get(basDevp.getDevNo());
|
if (staProtocol == null) {
|
continue;
|
} else {
|
staProtocol = staProtocol.clone();
|
}
|
if (basDevp.getWrkNo() != 0) {
|
if (basDevp.getAgvTargetPick() != 0) {//取货
|
staProtocol.setAgvTypeSign((short) 0);
|
staProtocol.setStaNo(basDevp.getDevNo().shortValue());
|
MessageQueue.offer(SlaveType.Devp, 1, new Task(4, staProtocol));
|
}
|
boolean sign = true;
|
if (basDevp.getAgvTargetPlace() != 0) {
|
sign = false;
|
basDevp.setAgvTargetPlace(0);
|
basDevpService.updateById(basDevp);
|
staProtocol.setAgvTypeSign((short) 3);//1
|
staProtocol.setStaNo(basDevp.getDevNo().shortValue());
|
MessageQueue.offer(SlaveType.Devp, 1, new Task(4, staProtocol));
|
}
|
} else {
|
if (basDevp.getAgvTargetPlace() != 0) {
|
if (basDevp.getLoading().equals("Y")) {
|
staProtocol.setAgvTypeSign((short) 1);
|
staProtocol.setStaNo(basDevp.getDevNo().shortValue());
|
MessageQueue.offer(SlaveType.Devp, 1, new Task(4, staProtocol));
|
} else {
|
log.error("AGV放货完成但输送线无物,复位信号 ===>> [staNo:{}] [basDevp:{}]", basDevp.getDevNo(), basDevp);
|
basDevp.setAgvTargetPlace(0);
|
basDevpService.updateById(basDevp);
|
staProtocol.setAgvTypeSign((short) 3);//1
|
staProtocol.setStaNo(basDevp.getDevNo().shortValue());
|
MessageQueue.offer(SlaveType.Devp, 1, new Task(4, staProtocol));
|
}
|
|
}
|
if (basDevp.getAgvTargetPick() != 0) {
|
basDevp.setAgvTargetPick(0);
|
basDevpService.updateById(basDevp);
|
staProtocol.setAgvTypeSign((short) 2);//0
|
staProtocol.setStaNo(basDevp.getDevNo().shortValue());
|
MessageQueue.offer(SlaveType.Devp, 1, new Task(4, staProtocol));
|
}
|
}
|
}
|
}
|
|
public synchronized void autoCompleteTask() {
|
List<TaskWrk> taskWrks = taskWrkMapper.selectWorkingTask();
|
for (TaskWrk taskWrk : taskWrks) {
|
//获取命令集合
|
List<CommandInfo> commandInfos = commandInfoService.selectByTaskNo(taskWrk.getTaskNo());
|
if (taskWrk.getCommandStep() < commandInfos.size()) {
|
continue;//当前步序没有到达最后一条命令
|
}
|
|
//判断末端命令是否执行完成
|
CommandInfo commandInfo = commandInfos.get(commandInfos.size() - 1);
|
if (commandInfo.getCommandStatus() != CommandStatusType.COMPLETE.id) {
|
continue;//指令未完成
|
}
|
|
Date now = new Date();
|
//指令已完成,更新任务
|
if (taskWrk.getIoType() == 1) {
|
//入库任务
|
taskWrk.setWrkSts(4);//3.吊车入库中 => 4.入库完成
|
//taskWrk.setStatus(TaskStatusType.COMPLETE.id);
|
taskWrk.setModiTime(now);
|
taskWrkService.updateById(taskWrk);
|
|
//更新库位状态
|
LocMast locMast = locMastService.selectByLocNo(taskWrk.getTargetPoint());
|
locMast.setLocSts("F");//F.在库
|
locMast.setBarcode(taskWrk.getBarcode());//托盘码
|
locMast.setModiTime(now);
|
locMast.setModiUser(9999L);
|
locMastService.updateById(locMast);
|
} else if (taskWrk.getIoType() == 2) {
|
//出库任务
|
taskWrk.setWrkSts(14);//12.吊车出库中 => 14.出库完成
|
// taskWrk.setStatus(TaskStatusType.COMPLETE.id);
|
taskWrk.setModiTime(now);
|
taskWrkService.updateById(taskWrk);
|
|
//更新库位状态
|
LocMast locMast = locMastService.selectByLocNo(taskWrk.getStartPoint());
|
locMast.setLocSts("O");//O.空库位
|
locMast.setBarcode("");//托盘码
|
locMast.setModiTime(now);
|
locMast.setModiUser(9999L);
|
locMastService.updateById(locMast);
|
}
|
}
|
}
|
|
}
|