Commit 5e351b95 zshaohui

1053 handle提交

1 个父辈 68ee9dd7
......@@ -524,5 +524,4 @@ public class StatusBean {
return newMsg;
}
}
}
......@@ -33,6 +33,23 @@ public enum OP_STATUS {
/**
* 已结束
*/
END
END,
/**
* 已从仓位中取出
*/
OUTBOX,
/**
* 机器人正在移栽中
*/
INROBOT,
/**
* 已放到料仓门口
*/
BOXDOOR,
/**
* 已放到料仓门口无料盘
*/
BOXDOOR_NOREEL
;
}
package com.neotel.smfcore.core.device.handler.impl;
import cn.hutool.core.util.ObjectUtil;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.common.utils.JsonUtil;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.bean.BoxStatusBean;
import com.neotel.smfcore.core.device.bean.StatusBean;
import com.neotel.smfcore.core.device.enums.BOX_STATUS;
import com.neotel.smfcore.core.device.enums.OP;
import com.neotel.smfcore.core.device.enums.OP_STATUS;
import com.neotel.smfcore.core.message.util.DeviceMessageUtil;
import com.neotel.smfcore.core.storage.enums.DeviceType;
import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.service.dao.IAlarmInfoDao;
import com.neotel.smfcore.core.system.service.po.AlarmInfo;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
@Api(tags = "RobotBox: 机器人料仓(1053)")
@RestController
@Slf4j
public class RobotBoxHandler extends BaseDeviceHandler {
@Autowired
private IAlarmInfoDao alarmInfoDao;
@Override
public StatusBean handleClientRequest(StatusBean statusBean, HttpServletRequest request) {
String cid = statusBean.getCid();
Storage storage = dataCache.getStorage(cid);
if (storage == null) {
log.error("料仓cid: [" + cid + "]不存在");
return null;
}
statusBean.setClientIp(request.getRemoteHost());
handleMsg(statusBean);
statusBean = saveAlarmAndHumidity(statusBean);
statusBean = handleFinished(statusBean);
StatusBean humidityResult = handleHumidity(statusBean);
if (humidityResult != null) {
return humidityResult;
}
if (statusBean.getOp() == OP.PUT_IN) {
log.debug("入库:" + statusBean.toString());
//判断是否有放在门口状态的入库任务
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if (queueTask.getCid().equals(statusBean.getCid()) && queueTask.isPutInTask() && queueTask.isBoxdoor()) {
String posId = queueTask.getPosName();
String reelId = queueTask.getBarcode();
Barcode barcode = barcodeManager.findByBarcode(reelId);
int plateW = barcode.getPlateSize();
int plateH = barcode.getHeight();
statusBean.addPosInfo(reelId, posId, plateW, plateH, false);
log.info(reelId + "[" + plateW + "x" + plateH + "]开始入库到" + storage.getCid() + "[" + posId + "]");
return statusBean;
}
}
//statusBean = putInLine(storage, statusBean);
} else {
//查看是否有要出库的操作
statusBean = findCheckOutTask(storage, statusBean);
}
return statusBean;
}
/**
* 出库处理
*/
public StatusBean findCheckOutTask(Storage storage, StatusBean statusBean) {
try {
//准备更新暂停出入库
if (dataCache.getCache(Constants.CACHE_StopOut)) {
return statusBean;
}
String cid = statusBean.getCid();
Collection<DataLog> queueTasks = taskService.getQueueTasks();
int executingOutTaskSize = 0;
DataLog outTask = null;
for (DataLog queueTask : queueTasks) {
if (queueTask.getCid().equals(cid)) {
//有入库任务不分配出库任务
if (queueTask.isPutInTask()) {
return statusBean;
} else {
if (queueTask.isExecuting()) {
executingOutTaskSize++;
//已经有出库任务正在执行,超过60秒仍未完成的出库再次发送到客户端
if (queueTask.needReSendToClient()) {
outTask = queueTask;
log.error("cid[" + cid + "]的出库任务[" + queueTask.getPosName() + "]超过60秒仍未完成,重新发送到客户端!");
queueTask.setUpdateDate(new Date());
break;
}
} else if (queueTask.isWait()) {
if (executingOutTaskSize >= 2) {
//log.error("cid["+cid + "]的BOX["+ boxId+"]的出库任务已经超过2个,不再分配!");
outTask = null;
break;
}
outTask = queueTask;
if (queueTask.isUrgentReel()) {
break;
}
}
}
}
}
if (outTask != null) {
log.info("分配出库任务" + outTask.getBarcode() + "[" + outTask.getPosName() + "]到 " + cid);
outTask.setStatus(OP_STATUS.EXECUTING.name());
taskService.updateQueueTask(outTask);
statusBean.setOp(OP.CHECKOUT);
String posName = outTask.getPosName();
Barcode codeObj = barcodeManager.findByBarcode(outTask.getBarcode());
int plateW = 0;
int plateH = 0;
if (codeObj != null) {
plateW = codeObj.getPlateSize();
plateH = codeObj.getHeight();
} else {
log.warn("出库无料仓位" + storage.getName() + "[" + posName + "]");
}
statusBean.addPosInfo(outTask.getBarcode(), posName, plateW, plateH, false);
log.info("出库" + storage.getName() + "[" + posName + "]物料[" + outTask.getBarcode() + "] 发送到客户端" + cid);
}
} catch (Exception e) {
log.error("出库出错", e);
}
return statusBean;
}
protected StatusBean handleFinished(StatusBean statusBean) {
Map<String, BoxStatusBean> statusOfBoxes = statusBean.getBoxStatus();
if (statusOfBoxes != null) {
for (BoxStatusBean boxStatus : statusOfBoxes.values()) {
try {
//出库入库完成处理
int status = boxStatus.getStatus();
String posName = boxStatus.getPosId();
int executeTime = boxStatus.getExecuteTime();
if (!Strings.isNullOrEmpty(posName)) {//客户端发一次完成之后,会发空的 posName,不需要处理
if (BOX_STATUS.IN_FINISHED == status) {//入仓完成
finishedPutIn(statusBean.getCid(), posName, executeTime);
} else if (BOX_STATUS.IN_FAILED == status) {//入库失败
//暂不处理
} else if (BOX_STATUS.OUT_FINISHED == status) {//出仓完成
finishedOutPos(statusBean.getCid(), posName, executeTime);
} else if (BOX_STATUS.OUT_END == status) {//出库完成(放到仓门口
//更改出库状态为OUT_DOOR
List<DataLog> finishedTasks = taskService.getFinishedTasks();
for (DataLog finishedTask : finishedTasks) {
if (finishedTask.getCid().equals(statusBean.getCid()) && finishedTask.isCheckOutTask() && finishedTask.isOutBox()) {
if (posName.equals(finishedTask.getPosName())) {
//已出仓但未放到门口,更改状态
finishedTask.setStatus(OP_STATUS.BOXDOOR.name());
taskService.updateFinishedTask(finishedTask);
log.info("物料" + finishedTask.getBarcode() + "已从库位" + finishedTask.getPosName() + "取出放到门口");
return statusBean;
}
}
}
log.error(posName + "出库放到门口时,未找到对应的出库任务");
} else if (BOX_STATUS.OUT_FAILED == status) {
//更改出库状态为OUT_DOOR
List<DataLog> finishedTasks = taskService.getFinishedTasks();
for (DataLog finishedTask : finishedTasks) {
if (finishedTask.getCid().equals(statusBean.getCid()) && finishedTask.isCheckOutTask() && finishedTask.isOutBox()) {
if (posName.equals(finishedTask.getPosName())) {
//已出仓但未放到门口,更改状态
finishedTask.setStatus(OP_STATUS.BOXDOOR_NOREEL.name());
log.info("物料" + finishedTask.getBarcode() + "已从库位" + finishedTask.getPosName() + "取出放到门口,但未感应到料盘,屏蔽库位");
StoragePos pos = storagePosManager.getByPosName(finishedTask.getPosName());
if (pos != null) {
pos.setEnabled(false);
storagePosManager.save(pos);
DeviceMessageUtil.addEnabledPosMessage(pos, "SYSTEM");
}
taskService.updateFinishedTask(finishedTask);
return statusBean;
}
}
}
}
}
} catch (ValidateException e) {
log.error("更新状态时出错" + e.getMessage());
}
}
}
return statusBean;
}
@ApiOperation("扫码后获取库位号")
@PostMapping(value = "/service/store/robotBox/emptyPosForPutin")
@ResponseBody
@AnonymousAccess
public Map<String, Object> emptyPosForPutin(HttpServletRequest request) {
String code = request.getParameter("code");
String cids = request.getParameter("cids");
String lastPosId = "";
String lineMsg = "";
log.info("流水线[" + cids + "]获取[" + code + "]的入库库位");
Map<String, Object> resultMap = Maps.newHashMap();
String okMsg = "";
String errorMsg = "";
List<Storage> storageList = Lists.newArrayList();
List<String> cidList = dataCache.getAvailableStorageIds(this.getDeviceType());
for (String cid : cidList) {
String notIntoCids = dataCache.getSettings().getNotIntoCids();
if (notIntoCids != null) {
if (notIntoCids.contains(cid)) {
log.info("料仓[" + cid + "]已被屏蔽入库");
continue;
}
}
Storage storage = dataCache.getStorage(cid);
if (storage != null) {
storageList.add(storage);
}
}
if (storageList.isEmpty()) {
resultMap.put("result", "99");
errorMsg = "无可用的料仓";
resultMap.put("msg", errorMsg);
} else {
try {
Barcode barcode = codeResolve.resolveOneValideBarcode(code);
for (DataLog dataLog : taskService.getQueueTasks()) {
if (dataLog.getBarcode().equals(barcode.getBarcode())) {
if (dataLog.isPutInTask()) {
//已有入库任务
errorMsg = "物料[" + dataLog.getBarcode() + "]已有入库任务,需继续执行入库动作";
resultMap.put("pos", dataLog.getPosName());
resultMap.put("barcode", barcode.getBarcode());
resultMap.put("cid", dataLog.getCid());
resultMap.put("taskId", dataLog.getId());
return resultMap;
} else {
//已有出库任务
errorMsg = "物料[" + dataLog.getBarcode() + "]已有出库任务,需继续执行出库动作";
resultMap.put("result", "98");
resultMap.put("msg", errorMsg);
resultMap.put("posId", dataLog.getPosName());
resultMap.put("plateW", barcode.getPlateSize());
resultMap.put("plateH", barcode.getHeight());
resultMap.put("singleOut", dataLog.isSingleOut() + "");
//紧急料
resultMap.put("urgentReel", dataLog.isUrgentReel() + "");
//需要分盘,进入分盘料
resultMap.put("cutReel", dataLog.isCutReel() + "");
resultMap.put("rfid", "");
resultMap.put("realRfid", "");
resultMap.put("rfidLoc", "");
resultMap.put("barcode", dataLog.getBarcode());
boolean smallReel = barcode.isSmallReel();
resultMap.put("smallReel", smallReel + "");
resultMap.put("taskId", dataLog.getId());
return resultMap;
}
}
}
/*try{
barcode = verifyPutInFromApi(barcode);
}catch (ValidateException ex){
lineMsg = "不允许入库," + ex.getDefaultMsg();
DeviceMessageUtil.updateLineMsg(lineMsg, code, cids, "", "smfcore.linemsg.update", null);
resultMap.put("result", "107");
resultMap.put("msg", lineMsg);
return resultMap;
}*/
StoragePos pos = taskService.findEmptyPosForPutIn(storageList, barcode, "", lastPosId);
if (pos != null) {
Storage storage = dataCache.getStorageById(pos.getStorageId());
//如果所在料仓有出库任务未完成,暂停入库
Collection<DataLog> tasks = taskService.getAllTasks();
for (DataLog task : tasks) {
if (task.isCheckOutTask() && task.getStorageId().equals(pos.getStorageId())) {
if (!task.isFinished() && !task.isInRobot()) {
errorMsg = "库位[" + pos.getPosName() + "]所在料仓有出库任务,暂停入库";
lineMsg = errorMsg;
resultMap.put("result", "99");
resultMap.put("msg", errorMsg);
return resultMap;
}
}
}
resultMap.put("result", "0");
resultMap.put("msg", "ok");
DataLog newTask = taskService.addPutInTaskToExecute(storage, barcode, pos);
okMsg = "[" + barcode.getBarcode() + "]锁定库位[" + pos.getPosName() + "]优先级[" + pos.getPriority() + "] 上个库位号[" + lastPosId + "]";
log.info(okMsg);
resultMap.put("pos", pos.getPosName());
resultMap.put("barcode", barcode.getBarcode());
resultMap.put("cid", storage.getCid());
resultMap.put("taskId", newTask.getId());
} else {
resultMap.put("result", "104");
errorMsg = "[" + barcode.getBarcode() + "]未找到可用的[" + barcode.getPlateSize() + "x" + barcode.getHeight() + "]仓位";
resultMap.put("msg", errorMsg);
}
} catch (ValidateException ve) {
errorMsg = ve.getMessage();
log.info("查找空库位失败:" + errorMsg);
resultMap.put("result", "105");
resultMap.put("msg", errorMsg);
} catch (Exception e) {
errorMsg = e.getMessage();
log.info("查找空库位失败,", e);
resultMap.put("result", "105");
resultMap.put("msg", errorMsg);
}
}
// }
//没入成功
if (!errorMsg.isEmpty()) {
//有错误,记录日志
AlarmInfo alarmInfo = new AlarmInfo();
alarmInfo.setBoxId("0");
alarmInfo.setStorageName("流水线");
alarmInfo.setInOutStatus("1");
alarmInfo.setAlarmType("入库");
Date date = new Date();
alarmInfo.setStartTime(date);
alarmInfo.setEndTime(date);
String msg = "[" + code + "]" + errorMsg;
alarmInfo.setAlarmMsg(msg);
alarmInfoDao.save(alarmInfo);
lineMsg = errorMsg;
DeviceMessageUtil.updateLineMsg(lineMsg, code, cids, "", "", null);
} else {
lineMsg = okMsg;
}
return resultMap;
}
@ApiOperation("机器人更新任务状态")
@PostMapping(value = "/service/store/robotBox/updateLocInfo")
@ResponseBody
@AnonymousAccess
public ResultBean updateLocInfo(HttpServletRequest request) {
String taskId = request.getParameter("taskId");
String barcode = request.getParameter("barcode");
String statusStr = request.getParameter("status");
String locInfo = request.getParameter("locInfo");
log.debug("收到料盘[" + barcode + "]更新位置指令[" + statusStr + "]=" + locInfo);
if (ObjectUtil.isEmpty(locInfo)) {
locInfo = statusStr;
}
DataLog opTask = null;
List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog task : allTasks) {
if (task.getId().equals(taskId) && task.getBarcode().equals(barcode)) {
opTask = task;
break;
}
}
if (opTask == null) {
return ResultBean.newErrorResult(301, "smfcore.task.notExist", "任务不存在");
}
if (opTask.isFinished()) {
return ResultBean.newErrorResult(302, "smfcore.task.hasEnd", "任务已完成");
}
// if (opTask.isCancel()) {
// return ResultBean.newErrorResult(303, "smfcore.task.hasCancel", "更新状态时{0}的出库任务[{1}]已被取消", new String[]{opTask.getBarcode(), opTask.getId()});
// }
statusStr = statusStr.toUpperCase();
log.info("更新料盘[" + barcode + "]的任务状态[" + opTask.getStatus() + "=" + opTask.getLocInfo() + "]为[" + statusStr + "=" + locInfo + "]");
opTask.setStatus(statusStr);
opTask.setLocInfo(locInfo);
//如果是出库任务并且放到料仓门口,需要发送任务给料仓
// if(task.isInBelt() || task.isPackageReel()){
// //已经放上皮带线
// AppendInfo appendInfo = task.getAppendInfo();
// if(org.apache.logging.log4j.util.Strings.isBlank(appendInfo.gethSerial())){
// log.info("手动出库料盘["+barcode+"]放上皮带线或包装料架,结束任务");
// task.setStatus(StorageConstants.OP_STATUS.FINISHED.name());
// }else if(appendInfo.isCheckAction()){
// log.info("盘点料盘["+barcode+"]放上皮带线或包装料架,结束任务");
// task.setStatus(StorageConstants.OP_STATUS.FINISHED.name());
// //盘点料,出到皮带线上即算完成
// int slotSeq = appendInfo.getSlotIndex();
// int sendQty = task.getNum();
// outInfoCache.incTaskFinishNum(appendInfo.gethSerial(),slotSeq, sendQty);
// }
// }
if (opTask.isPutInTask()) {
taskService.updateQueueTask(opTask);
} else {
taskService.updateFinishedTask(opTask);
}
return ResultBean.newOkResult("");
}
@ApiOperation("机器人定时获取任务")
@PostMapping(value = "/service/store/robotBox/getRobotTask")
@ResponseBody
@AnonymousAccess
public ResultBean getRobotTask(HttpServletRequest request) {
Collection<DataLog> datalogs = taskService.getAllTasks();
//先查找已在机器人的
// for (DataLog task : datalogs) {
// if (task.isInRobot()) {
// //获取任务失败,还有未完成的任务
// return ResultBean.newErrorResult(1, "smfcore.task.lastNotEnd", "上个任务未结束{0}{1}", new String[]{task.getPosName(), task.getBarcode()});
// }
// }
//查找出库已经到门口的
for (DataLog task : datalogs) {
if (task.isCheckOutTask()) {
if (task.isBoxdoor()) {
Map<String, String> taskMap = new HashMap<>();
taskMap.put("cid", task.getCid());//取料位置
// taskMap.put("targetPos", "out");//放料位置
taskMap.put("type", task.getType() + "");//类型,1=入库,2=出库
taskMap.put("posId", task.getPosName());
Barcode barcode = barcodeManager.findByBarcode(task.getBarcode());
int plateW = 0;
int plateH = 0;
if (barcode != null) {
plateW = barcode.getPlateSize();
plateH = barcode.getHeight();
}
taskMap.put("plateW", plateW + "");
taskMap.put("plateH", plateH + "");
taskMap.put("barcode", task.getBarcode());
taskMap.put("taskId", task.getId());
return ResultBean.newOkResult(taskMap);
}
}
}
return ResultBean.newErrorResult(-1, "", "");
}
@ApiOperation("料仓判断仓门口是否可以放料")
@PostMapping(value = "/service/store/robotBox/getBoxDoorStatus")
@ResponseBody
@AnonymousAccess
public ResultBean getBoxDoorStatus(HttpServletRequest request) {
String cid = request.getParameter("cid");
//判断仓门口状态,0=空闲,返回其他表示仓门口有料或机器人正在取料
Storage storage = dataCache.getStorage(cid);
if (storage == null) {
return ResultBean.newErrorResult(99, "smfcore.robotBox.notFound", "未找到机器人料仓[{0}]", new String[]{cid});
}
if (!storage.isRobotBox()) {
return ResultBean.newErrorResult(99, "smfcore.robotBox.notFound", "未找到机器人料仓[{0}]", new String[]{cid});
}
Collection<DataLog> tasks = taskService.getQueueTasks();
for (DataLog task : tasks) {
if (task.getStorageId().equals(storage.getId())) {
if (task.isBoxdoor()) {
return ResultBean.newErrorResult(-1, "smfcore.robotBox.boxHasTask", "任务[{0}][{1}]类型{2}状态{3}", new String[]{task.getPosName(), task.getBarcode(), task.getType() + "", task.getStatus()});
}
// else if(task.isPutInTask()&&task.isInRobot()){
// return ResultBean.newErrorResult(-1, "smfcore.robotBox.boxHasTask", "任务[{0}][{1}]类型{2}状态{3}", new String[]{task.getPosName(), task.getBarcode(),task.getType()+"", task.getStatus()});
// }
}
}
return ResultBean.newOkResult("");
}
@Override
public DeviceType getDeviceType() {
return DeviceType.ROBOT_BOX;
}
}
......@@ -5,10 +5,7 @@ import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.common.utils.QueryHelp;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.common.utils.YmlUpdateUtil;
import com.neotel.smfcore.common.utils.*;
import com.neotel.smfcore.core.barcode.service.manager.IComponentManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.barcode.service.po.Component;
......@@ -677,6 +674,21 @@ public class DataCache {
}
return availableStorageIds;
}
public List<String> getAvailableStorageIds(DeviceType deviceType){
List<String> availableStorageIds = new ArrayList<>();
for (Storage storage : getAllStorage().values()) {
if(storage.getType().equals(deviceType.name())) {
StatusBean bean = DevicesStatusUtil.getStatusBean(storage.getCid());
if (bean == null || bean.timeOut() || !bean.isAvailable()) {
continue;
}
availableStorageIds.add(storage.getCid());
}
}
return availableStorageIds;
}
public Storage AutoCreateStorage(String cid,String deviceType) {
//判断cid存在
Storage storage = null;
......@@ -710,4 +722,24 @@ public class DataCache {
}
return 0;
}
public String GetConfigCache(String cacheKey ,String configKey,String configValue) {
if (StringUtils.isEmpty(configKey) || StringUtils.isEmpty(cacheKey)) {
return configValue;
}
if (StringUtils.isEmpty(configValue)) {
String cacheValue = getCache(cacheKey);
if (cacheValue == null || StringUtils.isEmpty(cacheValue)) {
return configValue;
}
configValue = cacheValue;
Map<String, Object> updateMap = new HashMap<>();
updateMap.put(configKey, configValue);
YmlUpdateUtil.updateYamlFile(updateMap);
} else {
updateCache(cacheKey, configValue);
}
return configValue;
}
}
......@@ -309,4 +309,7 @@ public class Storage extends BasePo implements Serializable {
return getGroupId().equals(groupId);
}
public boolean isRobotBox() {
return DeviceType.ROBOT_BOX.name().equals(type);
}
}
......@@ -210,6 +210,11 @@ public class DataLog extends BasePo implements Serializable {
*/
private MSDAppendInfo msdAppendInfo;
/**
* 位置信息,如料架编号,托盘编号,移栽编号,皮带线编号,机器人编号等
*/
private String locInfo = "";
public String getBarcode() {
if(barcode == null){
return "";
......@@ -252,6 +257,13 @@ public class DataLog extends BasePo implements Serializable {
return OP_STATUS.END.name().equals(status);
}
public boolean isOutBox(){
return OP_STATUS.OUTBOX.name().equals(status);
}
public boolean isInRobot(){
return OP_STATUS.INROBOT.name().equals(status);
}
/**
* 是否是入库任务
......@@ -287,6 +299,14 @@ public class DataLog extends BasePo implements Serializable {
return OP.CHECKOUT == type;
}
public boolean isBoxdoor(){
return OP_STATUS.BOXDOOR.name().equals(status) || OP_STATUS.BOXDOOR_NOREEL.equals(status);
}
public boolean isBoxDoorNoReel(){
return OP_STATUS.BOXDOOR_NOREEL.equals(status);
}
/**
* 超过5分钟的已完成,已取消的任务都不再
*/
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!