src/main/java/com/zy/asrs/controller/OpenController.java
@@ -2,6 +2,9 @@ import com.core.common.R; import com.zy.asrs.domain.param.ToOutStaParam; import com.zy.asrs.entity.RcsReporterTask; import com.zy.asrs.entity.RcsReturn; import com.zy.asrs.service.RcsService; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.SlaveConnection; import com.zy.core.enums.SlaveType; @@ -9,6 +12,8 @@ import com.zy.core.model.protocol.StaProtocol; import com.zy.core.thread.SiemensDevpThread; 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.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -16,6 +21,8 @@ @Slf4j @RestController public class OpenController { @Autowired private RcsService rcsService; @RequestMapping("/open/toOutSta") public R toOutSta(@RequestBody ToOutStaParam param) { @@ -47,4 +54,11 @@ return R.ok().add(result); } // 反馈任务执行结果 @PostMapping("/api/robot/reporter/task") public RcsReturn reporterTask(@RequestBody RcsReporterTask param){ return rcsService.reporterTask(param); } } src/main/java/com/zy/asrs/entity/BasDevp.java
@@ -94,9 +94,9 @@ private String downing; /** * 需求1 * 料架 */ @ApiModelProperty(value= "需求1") @ApiModelProperty(value= "料架") private String inreq1; /** src/main/java/com/zy/asrs/entity/LocMast.java
@@ -174,6 +174,9 @@ @TableField("ctn_no") private String ctnNo; @ApiModelProperty(value= "拍照图片") private String pic; public String getIoTime$(){ if (Cools.isEmpty(this.ioTime)){ return ""; src/main/java/com/zy/asrs/entity/RcsReporterTask.java
New file @@ -0,0 +1,21 @@ package com.zy.asrs.entity; import com.alibaba.fastjson.JSONObject; import lombok.Data; // 任务执行反馈 @Data public class RcsReporterTask { // 任务号 private String robotTaskCode; // 当前执行任务的机器人唯一标识。 private String singleRobotCode; // 目标路径序列,0 起点序号,1 终点序号。 private Integer currentSeq; // 详细信息 private JSONObject extra; //华晓AGV任务状态及请求 private String method; } src/main/java/com/zy/asrs/entity/RcsReturn.java
New file @@ -0,0 +1,20 @@ package com.zy.asrs.entity; import com.alibaba.fastjson.JSONObject; import lombok.Data; // 海康返回 @Data public class RcsReturn { // SUCCESS 成功 // Err_TaskTypeNotSupport 任务类型不支持 // Err_RobotGroupsNotMatch 机器人资源组编号与任务不匹配,无法调度 // Err_RobotCodeNotMatch 机器人编号与任务不匹配,无法调度 // Err_TargetRouteError 任务路径参数有误 private String code; private String message; private JSONObject data; } src/main/java/com/zy/asrs/entity/RcsTaskContinue.java
New file @@ -0,0 +1,20 @@ package com.zy.asrs.entity; import lombok.Data; // 继续执行任务 @Data public class RcsTaskContinue { // 任务链编号 private String robotTaskCode; // 触发类型: //SITE 站点编号触发 //CARRIER 载具编号触发 //ROBOT 车号触发 //TASK 任务链编号触发 private String triggerType; // 与 triggerType 对应的触发编号 private String triggerCode; } src/main/java/com/zy/asrs/entity/Task.java
New file @@ -0,0 +1,488 @@ package com.zy.asrs.entity; import com.baomidou.mybatisplus.annotations.TableField; import com.baomidou.mybatisplus.annotations.TableId; import com.baomidou.mybatisplus.annotations.TableName; import com.baomidou.mybatisplus.enums.IdType; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.Cools; import com.core.common.SpringUtils; import com.zy.asrs.service.BasCrnpService; import com.zy.asrs.service.LocMastService; import com.zy.system.entity.User; import com.zy.system.service.UserService; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; import java.io.Serializable; import java.text.SimpleDateFormat; import java.util.Date; @Data @TableName("agv_task") @Accessors(chain = true) public class Task implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty(value= "") @TableId(value = "id", type = IdType.AUTO) private Long id; /** * 任务类型: agv , crn */ @ApiModelProperty(value= "任务类型: agv , crn") @TableField("task_type") private String taskType; /** * 工作号 */ @ApiModelProperty(value= "工作号") @TableField("wrk_no") private Integer wrkNo; @ApiModelProperty(value= "下发AGV任务计数") @TableField("ctn_type") private Integer ctnType=0; @ApiModelProperty(value= "") @TableField("inv_wh") private String invWh; @ApiModelProperty(value= "") private Date ymd; @ApiModelProperty(value= "") private String mk; @ApiModelProperty(value= "") @TableField("whs_type") private Integer whsType; /** * 工作状态 */ @ApiModelProperty(value= "工作状态") @TableField("wrk_sts") private Long wrkSts; /** * 入出库类型 * 3.站到站 * 4.站到区域 * 5.区域到站 */ @ApiModelProperty(value= "入出库类型") @TableField("io_type") private Integer ioType; /** * 堆垛机 */ @ApiModelProperty(value= "堆垛机") @TableField("crn_no") private Integer crnNo; @ApiModelProperty(value= "") @TableField("sheet_no") private String sheetNo; /** * 优先级 */ @ApiModelProperty(value= "优先级") @TableField("io_pri") private Double ioPri; @ApiModelProperty(value= "") @TableField("wrk_date") private Date wrkDate; /** * 目标库位 */ @ApiModelProperty(value= "目标库位") @TableField("loc_no") private String locNo; /** * 目标站 */ @ApiModelProperty(value= "目标站") @TableField("sta_no") private String staNo; /** * 源站 */ @ApiModelProperty(value= "源站") @TableField("source_sta_no") private String sourceStaNo; /** * 源库位 */ @ApiModelProperty(value= "源库位") @TableField("source_loc_no") private String sourceLocNo; @ApiModelProperty(value= "") @TableField("loc_sts") private String locSts; @ApiModelProperty(value= "1.海康AGV 2.华晓AGV 默认是1.海康") @TableField("plt_type") private Integer pltType=1; @ApiModelProperty(value= "料架号") private String packed; /** * 拣料 */ @ApiModelProperty(value= "拣料") private String picking; @ApiModelProperty(value= "") @TableField("link_mis") private String linkMis; @ApiModelProperty(value= "") @TableField("online_yn") private String onlineYn; @ApiModelProperty(value= "是否任务报错") @TableField("upd_mk") private String updMk; /** * 退出 */ @ApiModelProperty(value= "退出") @TableField("exit_mk") private String exitMk; /** * 空板 */ @ApiModelProperty(value= "空板") @TableField("empty_mk") private String emptyMk; /** * 工作时间 */ @ApiModelProperty(value= "工作时间") @TableField("io_time") private Date ioTime; @ApiModelProperty(value= "") @TableField("ove_mk") private String oveMk; @ApiModelProperty(value= "") @TableField("mtn_type") private Double mtnType; @ApiModelProperty(value= "") @TableField("user_no") private String userNo; /** * 堆垛机启动时间 */ @ApiModelProperty(value= "堆垛机启动时间") @TableField("crn_str_time") private Date crnStrTime; /** * 堆垛机停止时间 */ @ApiModelProperty(value= "堆垛机停止时间") @TableField("crn_end_time") private Date crnEndTime; @ApiModelProperty(value= "") @TableField("plc_str_time") private Date plcStrTime; @ApiModelProperty(value= "") @TableField("crn_pos_time") private Date crnPosTime; @ApiModelProperty(value= "") @TableField("load_time") private Double loadTime; @ApiModelProperty(value= "") @TableField("exp_time") private Double expTime; @ApiModelProperty(value= "") @TableField("ref_wrkno") private Double refWrkno; /** * 拣料时间 */ @ApiModelProperty(value= "拣料时间") @TableField("ref_iotime") private Date refIotime; /** * 修改人员 */ @ApiModelProperty(value= "修改人员") @TableField("modi_user") private Long modiUser; /** * 修改时间 */ @ApiModelProperty(value= "修改时间") @TableField("modi_time") private Date modiTime; /** * 创建者 */ @ApiModelProperty(value= "创建者") @TableField("appe_user") private Long appeUser; /** * 添加时间 */ @ApiModelProperty(value= "添加时间") @TableField("appe_time") private Date appeTime; @ApiModelProperty(value= "") @TableField("pause_mk") private String pauseMk; @ApiModelProperty(value= "") @TableField("error_time") private Date errorTime; @ApiModelProperty(value= "") @TableField("error_memo") private String errorMemo; @ApiModelProperty(value= "") @TableField("ctn_kind") private Integer ctnKind; @ApiModelProperty(value= "") @TableField("manu_type") private String manuType; /** * 备注 */ @ApiModelProperty(value= "备注") private String memo; @ApiModelProperty(value= "") @TableField("sc_weight") private Double scWeight; @ApiModelProperty(value= "") @TableField("log_mk") private String logMk; @ApiModelProperty(value= "") @TableField("log_err_time") private Date logErrTime; @ApiModelProperty(value= "") @TableField("log_err_memo") private String logErrMemo; /** * 条码 */ @ApiModelProperty(value= "条码") private String barcode; // Y:销售订单出库任务 @ApiModelProperty(value= "") @TableField("Pdc_type") private String PdcType; @ApiModelProperty(value= "") @TableField("ctn_no") private String ctnNo; /** * 满板 */ @ApiModelProperty(value= "满板") @TableField("full_plt") private String fullPlt; /** * 先入品 / 双重入库 */ @ApiModelProperty(value= "先入品") @TableField("pre_have") private String preHave; /** * 空操作 / 取货无箱 */ @ApiModelProperty(value= "空操作") @TableField("take_none") private String takeNone; /** * 外部任务编号 */ @ApiModelProperty(value= "外部任务编号") @TableField("task_no") private String taskNo; public Task() {} public String getYmd$(){ if (Cools.isEmpty(this.ymd)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.ymd); } public String getCrnNo$(){ BasCrnpService service = SpringUtils.getBean(BasCrnpService.class); BasCrnp basCrnp = service.selectById(this.crnNo); if (!Cools.isEmpty(basCrnp)){ return String.valueOf(basCrnp.getCrnNo()); } return null; } public String getWrkDate$(){ if (Cools.isEmpty(this.wrkDate)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.wrkDate); } public String getLocNo$(){ LocMastService service = SpringUtils.getBean(LocMastService.class); LocMast locMast = service.selectById(this.locNo); if (!Cools.isEmpty(locMast)){ return String.valueOf(locMast.getLocNo()); } return null; } public String getTaskType$(){ if (Cools.isEmpty(this.taskType)){return null;} if (taskType.equals("AGV")) { return "AGV任务"; } else { return "堆垛机任务"; } } public String getSourceLocNo$(){ LocMastService service = SpringUtils.getBean(LocMastService.class); LocMast locMast = service.selectById(this.sourceLocNo); if (!Cools.isEmpty(locMast)){ return String.valueOf(locMast.getLocNo()); } return null; } public String getIoTime$(){ if (Cools.isEmpty(this.ioTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.ioTime); } public String getCrnStrTime$(){ if (Cools.isEmpty(this.crnStrTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.crnStrTime); } public String getCrnEndTime$(){ if (Cools.isEmpty(this.crnEndTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.crnEndTime); } public String getPlcStrTime$(){ if (Cools.isEmpty(this.plcStrTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.plcStrTime); } public String getCrnPosTime$(){ if (Cools.isEmpty(this.crnPosTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.crnPosTime); } public String getRefIotime$(){ if (Cools.isEmpty(this.refIotime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.refIotime); } public String getModiUser$(){ UserService service = SpringUtils.getBean(UserService.class); User user = service.selectById(this.modiUser); if (!Cools.isEmpty(user)){ return String.valueOf(user.getUsername()); } return null; } public String getModiTime$(){ if (Cools.isEmpty(this.modiTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.modiTime); } public String getAppeUser$(){ UserService service = SpringUtils.getBean(UserService.class); User user = service.selectById(this.appeUser); if (!Cools.isEmpty(user)){ return String.valueOf(user.getUsername()); } return null; } public String getAppeTime$(){ if (Cools.isEmpty(this.appeTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.appeTime); } public String getErrorTime$(){ if (Cools.isEmpty(this.errorTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.errorTime); } public String getLogErrTime$(){ if (Cools.isEmpty(this.logErrTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.logErrTime); } } src/main/java/com/zy/asrs/entity/TransInOutStationAllow.java
New file @@ -0,0 +1,29 @@ package com.zy.asrs.entity; import lombok.Data; import lombok.EqualsAndHashCode; // 入站允许、离站允许 @EqualsAndHashCode(callSuper = true) @Data public class TransInOutStationAllow extends TransParent { //任务编号 private String taskno; //任务名称 private String taskname; //AGV编号 private String AgvCode; //运输类型 private String TransType; //生产线编号 private String ProductLineId; //工位编号 private String StationId; //任务类型 private String taskType; // 是否允许,Y 允许;N,不允许 private String status; } src/main/java/com/zy/asrs/entity/TransParent.java
New file @@ -0,0 +1,39 @@ package com.zy.asrs.entity; import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; // 出入站请求继承父类:入站请求、入站允许、离站请求、离站允许、离站完成 @Data public class TransParent { // 任务编号,wcs_task_header表中的task_no private String taskno; // 任务名称,wcs_task_header表中的task_name private String taskname; // AGV编码 @JsonProperty("AgvCode") @JSONField(name = "AgvCode") private String AgvCode; // 运输类型 @JsonProperty("TransType") @JSONField(name = "TransType") private String TransType; // 生产线编码 @JsonProperty("ProductLineId") @JSONField(name = "ProductLineId") private String ProductLineId; // 工位编码 @JsonProperty("StationId") @JSONField(name = "StationId") private String StationId; // 任务类型 @JsonProperty("TaskType") @JSONField(name = "TaskType") private String TaskType; //请求类型 private String method; } src/main/java/com/zy/asrs/entity/WrkMast.java
@@ -48,6 +48,14 @@ private Integer whsType; /** * 0:需要创建agv搬运空料架任务 * 1:wms成功创建agv搬运空料架任务 */ @ApiModelProperty(value= "需要下发agv任务的状态") @TableField("ctn_type") private Integer ctnType; /** * 工作状态 */ @ApiModelProperty(value= "工作状态") @@ -157,10 +165,6 @@ @ApiModelProperty(value= "工作时间") @TableField("io_time") private Date ioTime; @ApiModelProperty(value= "") @TableField("ctn_type") private Integer ctnType; @ApiModelProperty(value= "") private String packed; @@ -309,6 +313,10 @@ @TableField("full_plt") private String fullPlt; @ApiModelProperty(value= "拍照图片") private String pic; public String getWrkSts$(){ BasWrkStatusMapper mapper = SpringUtils.getBean(BasWrkStatusMapper.class); BasWrkStatus entity = mapper.selectById(this.wrkSts); src/main/java/com/zy/asrs/enums/RcsRetMethodEnum.java
New file @@ -0,0 +1,45 @@ package com.zy.asrs.enums; public enum RcsRetMethodEnum { TASK_START("start", "任务开始"), TASK_OUT_BIN("outbin", "走出储位"), APPLY_IN_STATION("applyInStation", "入站请求"), APPLY_OFF_STATION("applyOutStation", "离站请求"), ARRIVE_ON_STATION("arriveOnStation", "到站完成"), ARRIVE_OFF_STATION("arriveOffStation", "离站完成"), APPLY_PUT("applyPut", "放货申请"), TASK_END("end", "任务完成"), APPLY_PICK("applyPick", "取货申请"), PICK_COMPLETE("pickComplete", "rcs取货完成,已退出输送线"); private String code; private String message; RcsRetMethodEnum(String code, String message) { this.code = code; this.message = message; } public static RcsRetMethodEnum getEnum(String code) { for (RcsRetMethodEnum method : RcsRetMethodEnum.values()) { if (method.getCode().equals(code)) { return method; } } return null; } public String getCode() { return code; } public String getMessage() { return message; } } src/main/java/com/zy/asrs/mapper/TaskMapper.java
New file @@ -0,0 +1,8 @@ package com.zy.asrs.mapper; import com.baomidou.mybatisplus.mapper.BaseMapper; import com.zy.asrs.entity.Task; public interface TaskMapper extends BaseMapper<Task> { } src/main/java/com/zy/asrs/service/RcsService.java
New file @@ -0,0 +1,15 @@ package com.zy.asrs.service; import com.zy.asrs.entity.RcsReporterTask; import com.zy.asrs.entity.RcsReturn; public interface RcsService { /** * 2.2.1任务执行回馈 * * @param rcsReporterTask * @return */ RcsReturn reporterTask(RcsReporterTask rcsReporterTask); } src/main/java/com/zy/asrs/service/TaskService.java
New file @@ -0,0 +1,9 @@ package com.zy.asrs.service; import com.baomidou.mybatisplus.service.IService; import com.zy.asrs.entity.Task; import java.util.List; public interface TaskService extends IService<Task> { } src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -13,16 +13,14 @@ import com.zy.asrs.mapper.WrkMastMapper; import com.zy.asrs.service.*; import com.zy.asrs.utils.Utils; import com.zy.asrs.utils.VersionUtils; import com.zy.common.constant.RedisConstantType; import com.zy.common.model.LocTypeDto; import com.zy.common.model.MatDto; import com.zy.common.model.SearchLocParam; import com.zy.common.model.StartupDto; import com.zy.common.service.CommonService; import com.zy.common.utils.CollectionUtils; import com.zy.common.utils.HttpHandler; import com.zy.common.utils.News; import com.zy.common.utils.RedisUtil; import com.zy.common.utils.*; import com.zy.core.CrnThread; import com.zy.core.DevpThread; import com.zy.core.cache.MessageQueue; @@ -49,6 +47,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; @@ -100,6 +99,9 @@ @Value("${wms.url}") private String wmsUrl; @Autowired private HikUtils hikUtils; /** * 组托 * 入库站,根据条码扫描生成入库工作档,工作状态 2 @@ -136,9 +138,7 @@ && staProtocol.isInEnable() && !staProtocol.isEmptyMk() && staProtocol.getWorkNo() == 9999 && staProtocol.isPakMk() // && (staProtocol.getEmptyInType() != 1 && staProtocol.getEmptyInType() != 2) ) { && staProtocol.isPakMk()) { News.warnNoLog("" + mark + " - 0" + " - 开始执行"); String barcode = barcodeThread.getBarcode(); @@ -422,7 +422,7 @@ // 更新站点信息 且 下发plc命令 staProtocol.setWorkNo(wrkMast.getWrkNo().shortValue()); staProtocol.setStaNo(wrkMast.getStaNo().shortValue()); staProtocol.setPalletSize(locMast.getLocType2()); // staProtocol.setPalletSize(locMast.getLocType2()); devpThread.setPakMk(staProtocol.getSiteId(), false); boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol)); if (!result) { @@ -959,14 +959,12 @@ * 入库 ===>> 堆垛机站到库位 */ public synchronized void crnStnToLoc(CrnSlave slave, CrnProtocol crnProtocol, Integer mark) { News.warnNoLog("" + mark + " - 1" + " - 0" + " - 堆垛机入出库作业下发:执行入库"); for (CrnSlave.CrnStn crnStn : slave.getCrnInStn()) { boolean flag = false; // 获取堆垛机入库站信息 DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId()); StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo()); if (staProtocol == null) { News.infoNoLog("" + mark + " - 1" + " - 1" + " - 堆垛机入库站信息(staProtocol!=null继续执行):staProtocol=" + staProtocol); continue; } else { staProtocol = staProtocol.clone(); @@ -974,7 +972,7 @@ // 查询站点详细信息 BasDevp staDetl = basDevpService.selectById(crnStn.getStaNo()); if (staDetl == null) { News.error("" + mark + " - 1" + " - 2" + " - 入库 ===>> 堆垛机站点在数据库不存在, 站点编号={}", crnStn.getStaNo()); News.error("入库 ===>> 堆垛机站点在数据库不存在, 站点编号={}", crnStn.getStaNo()); continue; } if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.getWorkNo() > 0 && staProtocol.isInEnable() @@ -982,33 +980,27 @@ flag = true; } if (!flag) { News.errorNoLog("" + mark + " - 1" + " - 3" + " - 堆垛机入库站信息(以下需要全true):" + "自动信号" + staProtocol.isAutoing() + "有物信号" + staProtocol.isLoading() + "工作号>0" + staProtocol.getWorkNo() + "可入信号" + staProtocol.isInEnable() + "能入信号(wms设置).equals(\"Y\")" + staDetl.getCanining()); continue; } // 获取工作状态为2(设备上走)的入库工作档 WrkMast wrkMast = wrkMastMapper.selectPakInStep2(slave.getId(), staProtocol.getWorkNo().intValue(), crnStn.getStaNo()); if (null == wrkMast) { News.infoNoLog("" + mark + " - 1" + " - 4" + " - 查询无待入库数据--wrk_sts=2, 工作号={}", staProtocol.getWorkNo()); // log.error("查询无待入库数据--wrk_sts=2, 工作号={}", staProtocol.getWorkNo()); continue; } // 获取库位信息 LocMast locMast = locMastService.selectById(wrkMast.getLocNo()); if (locMast == null) { News.error("" + mark + " - 1" + " - 5" + " - 查询库存无数据--库位号{}", wrkMast.getLocNo()); News.error("查询库存无数据--库位号{}", wrkMast.getLocNo()); continue; } if (!locMast.getLocSts().equals("S") && !locMast.getLocSts().equals("Q")) { News.error("" + mark + " - 1" + " - 6" + " - 入库操作库位状态不符合--状态, 库位号={},库位状态={}", wrkMast.getLocNo(), locMast.getLocSts()); News.error("入库操作库位状态不符合--状态, 库位号={},库位状态={}", wrkMast.getLocNo(), locMast.getLocSts()); continue; } // 堆垛机控制过滤 if (!crnProtocol.getStatusType().equals(CrnStatusType.IDLE) || crnProtocol.getTaskNo() != 0) { // News.infoNoLog(""+mark+" - 1"+" - 7"+" - 堆垛机控制过滤:堆垛机是否空闲={},任务号={}", crnProtocol.getStatusType(),crnProtocol.getTaskNo()); continue; } @@ -1017,89 +1009,92 @@ continue; } // if (crnProtocol.getCrnNo() == 1) { // //判断堆垛机和当前任务是否处于一个巷道 // if (Utils.getLaneByLocNo(wrkMast.getLocNo()) != crnProtocol.getCrnLane()) { // //判断堆垛机所在巷道是否存在其他任务,如存在则优先执行 // List<WrkMast> currentWrkMasts = wrkMastService.selectLaneWrkMast(crnProtocol.getCrnLane(), false); //// if (!currentWrkMasts.isEmpty()) { //// continue;//当前堆垛机所在巷道存在任务 //// } // } // } // 双深库位且浅库位有货,则需先对浅库位进行库位移转 if (Utils.isDeepLoc(slaveProperties, wrkMast.getLocNo())) { News.warnNoLog("" + mark + " - 1" + " - 8" + " - 双深库位且浅库位有货,则需先对浅库位进行库位移转 : 开始执行 任务号={}", wrkMast.getWrkNo()); String shallowLocNo = Utils.getShallowLoc(slaveProperties, wrkMast.getLocNo()); LocMast shallowLoc = locMastService.selectById(shallowLocNo); // O.空库位、Q.拣料/盘点/并板再入库、S.入库预约、X.禁用 直接搬! if (shallowLoc.getLocSts().equals("P") || shallowLoc.getLocSts().equals("R")) { News.warn("" + mark + " - 1" + " - 9" + " - // O.空库位、Q.拣料/盘点/并板再入库、S.入库预约、X.禁用 直接搬!库位={},库位状态={}", shallowLoc.getLocNo(), shallowLoc.getLocSts()); WrkMast waitWrkMast = wrkMastMapper.selectByLocNo(shallowLocNo); if (null == waitWrkMast) { News.error("" + mark + " - 1" + " - 10" + " - {}库位异常,未检索到相应工作档!", shallowLocNo); News.error("{}库位异常,未检索到相应工作档!", shallowLocNo); } else { if (waitWrkMast.getWrkSts() != 14 && waitWrkMast.getIoType() > 100) { waitWrkMast.setIoPri(15D); waitWrkMast.setModiTime(new Date()); if (wrkMastMapper.updateById(waitWrkMast) == 0) { News.error("" + mark + " - 1" + " - 11" + " - 调整工作档优先级失败!工作号={}", waitWrkMast.getWrkNo()); } continue; waitWrkMast.setIoPri(15D); waitWrkMast.setModiTime(new Date()); if (wrkMastMapper.updateById(waitWrkMast) == 0) { News.error("调整工作档优先级失败!工作号={}", waitWrkMast.getWrkNo()); } if (waitWrkMast.getWrkSts() < 5 && waitWrkMast.getIoType() < 100) { continue;//有任务禁止搬运,有可能浅库位状态还未变更完成 } continue; } } else if (shallowLoc.getLocSts().equals("F") || shallowLoc.getLocSts().equals("D")) { News.warn("" + mark + " - 1" + " - 12" + " - // F、D 库位={},库位状态={}", shallowLoc.getLocNo(), shallowLoc.getLocSts()); // 此标记避免多次执行移库任务 if (Cools.isEmpty(wrkMast.getUpdMk()) || "N".equals(wrkMast.getUpdMk())) { if (moveLocForDeepLoc(slave, crnProtocol, shallowLoc, mark)) { wrkMast.setUpdMk("Y"); wrkMast.setIoPri(14D); wrkMastMapper.updateById(wrkMast); } // wrkMast.setUpdMk("Y"); // wrkMast.setIoPri(14D); // wrkMastMapper.updateById(wrkMast); // // 生成工作档,将浅库位移转到新的库位中 // moveLocForDeepLoc(slave, shallowLoc,mark); wrkMast.setUpdMk("Y"); wrkMast.setIoPri(14D); wrkMastMapper.updateById(wrkMast); // 生成工作档,将浅库位移转到新的库位中 moveLocForDeepLoc(slave, shallowLoc); // 生成工作档、改变浅库位的源库/目标库 库位状态、下发堆垛机命令(立马执行) // moveLocForDeepLocPakin(slave, shallowLoc, wrkMast); } continue; } else if (shallowLoc.getLocSts().equals("Q")) { News.warn("" + mark + " - 1" + " - 13" + " - // Q 库位={},库位状态={}", shallowLoc.getLocNo(), shallowLoc.getLocSts()); WrkMast waitWrkMast = wrkMastMapper.selectByLocNo(shallowLocNo); if (null != waitWrkMast && waitWrkMast.getWrkSts() == 4) { News.infoNoLog("" + mark + " - 1" + " - 14" + " - // F、D 工作状态(判断条件为==4)={}", waitWrkMast.getWrkSts()); continue; } } } News.info("" + mark + " - 1" + " - 15" + " - 命令下发 : 工作号={},源排={},源列={},源层={},目标排={},目标列={},目标层={}", wrkMast.getWrkNo().shortValue() , crnStn.getRow().shortValue(), crnStn.getBay().shortValue(), crnStn.getLev().shortValue() , locMast.getRow1().shortValue(), locMast.getBay1().shortValue(), locMast.getLev1().shortValue()); String ip = ""; if (wrkMast.getStaNo()==401){ ip = "172.26.4.231"; }else if (wrkMast.getStaNo()==402){ ip = "172.26.4.232"; }else if (wrkMast.getStaNo()==307){ ip = "172.26.1.231"; }else if (wrkMast.getStaNo()==303){ ip = "172.26.1.232"; }else if (wrkMast.getStaNo()==304){ ip = "172.26.1.233"; } SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss"); String newName = sf.format(new Date()) + "_" + locMast.getLocNo(); String pic = wrkMast.getPic(); List<String> list = null; if (Cools.isEmpty(pic)) { list = new ArrayList<>(); } else { list = JSON.parseArray(pic, String.class); } list.add(newName); //入库前抓拍 try { hikUtils.startPic(ip, newName + ".jpg"); } catch (Exception e) { log.error("入库前抓拍"); } // 命令下发区 -------------------------------------------------------------------------- CrnCommand crnCommand = new CrnCommand(); crnCommand.setCrnNo(slave.getId()); // 堆垛机编号 crnCommand.setTaskNo(wrkMast.getWrkNo().shortValue()); // 工作号 // crnCommand.setAckFinish((short) 0); // 任务完成确认位 crnCommand.setAckFinish((short) 0); // 任务完成确认位 crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE); // 任务模式: 库位移转 crnCommand.setSourcePosX(crnStn.getRow().shortValue()); // 源库位排 crnCommand.setSourcePosY(crnStn.getBay().shortValue()); // 源库位列 crnCommand.setSourcePosZ(crnStn.getLev().shortValue()); // 源库位层 crnCommand.setDestinationPosX(locMast.getRow1().shortValue()); // 目标库位排 crnCommand.setDestinationPosY(locMast.getBay1().shortValue()); // 目标库位列 crnCommand.setDestinationPosZ(locMast.getLev1().shortValue()); // 目标库位层 crnCommand.setDestinationPosZ(locMast.getLev1().shortValue()); // 目标库位层\ crnCommand.setBarcode(wrkMast.getBarcode());//托盘码 log.error("768 堆垛机命令下发" + crnCommand); if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getCrnNo(), new Task(2, crnCommand))) { News.error("" + mark + " - 1" + " - 16" + " - 堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMast.getCrnNo(), JSON.toJSON(crnCommand)); News.error("堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMast.getCrnNo(), JSON.toJSON(crnCommand)); } else { log.error("772 堆垛机命令下发成功" + crnCommand); News.info("772 堆垛机命令下发成功" + crnCommand); // long startTime = System.currentTimeMillis(); // while ((System.currentTimeMillis() - startTime) < COMMAND_TIMEOUT) { @@ -1114,16 +1109,20 @@ // } // 修改工作档状态 2.设备上走 => 3.吊车入库中 log.error("787 修改工作档状态2.设备上走 => 3.吊车入库中 " + wrkMast); News.info("787 修改工作档状态2.设备上走 => 3.吊车入库中 " + wrkMast); Date now = new Date(); wrkMast.setWrkSts(3L); wrkMast.setPic(JSON.toJSONString(list)); wrkMast.setCrnStrTime(now); wrkMast.setModiTime(now); if (wrkMastMapper.updateById(wrkMast) == 0) { News.error("" + mark + " - 1" + " - 17" + " - 修改工作档状态 2.设备上走 => 3.吊车入库中 失败!!,工作号={}", wrkMast.getWrkNo()); News.error("修改工作档状态 2.设备上走 => 3.吊车入库中 失败!!,工作号={}", wrkMast.getWrkNo()); } log.error("795 修改工作档状态成功2.设备上走 => 3.吊车入库中" + wrkMast); News.info("795 修改工作档状态成功2.设备上走 => 3.吊车入库中" + wrkMast); } } News.infoNoLog("" + mark + " - 1" + " - 0" + " - 堆垛机入出库作业下发 : 入库执行完毕"); } /** @@ -1131,35 +1130,6 @@ * 2022-06-09 TQS修改,查询工作档LIST,遍历下发,防止第一个任务堵塞出库 */ public synchronized void locToCrnStn(CrnSlave slave, CrnProtocol crnProtocol, Integer mark) { News.warnNoLog("" + mark + " - 2" + " - 0" + " - 堆垛机入出库作业下发:执行出库"); // int devpTaskStackOver = 20; // Config config = configService.selectOne(new EntityWrapper<Config>() // .eq("code", "devpTaskStackOver")); // if (config != null) { // devpTaskStackOver = Integer.parseInt(config.getValue()); // } // int devpCheckTaskStackOver = 2; // Config config2 = configService.selectOne(new EntityWrapper<Config>() // .eq("code", "devpCheckTaskStackOver")); // if (config2 != null) { // devpCheckTaskStackOver = Integer.parseInt(config2.getValue()); // } // // int outNumber = 13; // Config config3 = configService.selectOne(new EntityWrapper<Config>() // .eq("code", "fullBoardOutboundNumber")); // if (config3 != null) { // outNumber = Integer.parseInt(config3.getValue()); // } // // // Integer devpWorkingCount = commonService.queryDevpWorkingCount(); // if (devpWorkingCount > devpTaskStackOver) { // News.warn("" + mark + " - 2" + " - 0" + " - 输送线任务过载,当前输送线承载数量:{}", devpWorkingCount); // return; // } for (CrnSlave.CrnStn crnStn : slave.getCrnOutStn()) { // 获取工作状态为11(生成出库ID)的出库工作档 // WrkMast wrkMast = wrkMastMapper.selectPakOutStep1(slave.getId(), crnStn.getStaNo()); @@ -1170,106 +1140,68 @@ } // 工作档状态判断 if (wrkMast.getIoType() < 100 || wrkMast.getSourceStaNo() == null) { News.error("" + mark + " - 2" + " - 1" + " - 查询工作档数据不符合条件--入出类型/站点, 工作号={},源库位={},入出类型={}", wrkMast.getWrkNo(), wrkMast.getSourceLocNo(), wrkMast.getIoType()); News.error("查询工作档数据不符合条件--入出类型/站点, 工作号={},源库位={},入出类型={}", wrkMast.getWrkNo(), wrkMast.getSourceLocNo(), wrkMast.getIoType()); continue; } // 获取源库位信息 LocMast sourceSta = locMastService.selectById(wrkMast.getSourceLocNo()); if (!sourceSta.getLocSts().equals("R") && !sourceSta.getLocSts().equals("P")) { News.error("" + mark + " - 2" + " - 2" + " - 出库操作库位状态不符合--状态, 库位号={},库位状态={}", wrkMast.getLocNo(), sourceSta.getLocSts()); News.error("出库操作库位状态不符合--状态, 库位号={},库位状态={}", wrkMast.getLocNo(), sourceSta.getLocSts()); continue; } // 获取堆垛机出库站信息 SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId()); StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo()); if (staProtocol == null) { News.infoNoLog("" + mark + " - 2" + " - 3" + " - 堆垛机出库站信息(staProtocol!=null继续执行,否则循环终止):staProtocol=" + staProtocol); break; // continue; } else { staProtocol = staProtocol.clone(); } // if (wrkMast.getStaNo() == 1003 || wrkMast.getStaNo() == 1007 || wrkMast.getStaNo() == 1004) { // //检测是否有入库任务 // List<WrkMast> inWrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>() // .in("io_type", 1, 53, 57) // .notIn("wrk_sts", 3, 4, 5) // .in("source_sta_no", 1002, 1007) // ); // if (!inWrkMasts.isEmpty()) { // News.error("" + mark + " - 2" + " - 检测存在入库任务,等待入库任务执行完成再出库,工作号={}" + wrkMast.getWrkNo()); // continue; // } // } //zhangc // if (wrkMast.getIoType() == 103 || wrkMast.getIoType() == 107) { // if (wrkMast.getStaNo() == 1058) { // List<WrkMast> inWrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>() // .in("wrk_sts", 12, 14) // .eq("sta_no", 1058) // ); // if (!Cools.isEmpty(inWrkMasts) && inWrkMasts.size() >= devpCheckTaskStackOver) { // News.error("" + mark + " - 2" + " - 检测存在1058站点,存在两笔工作中的任务,工作号={}" + wrkMast.getWrkNo()); // continue; // } // } else if (wrkMast.getStaNo() == 1062) { // List<WrkMast> inWrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>() // .in("wrk_sts", 12, 14) // .eq("sta_no", 1062) // ); // if (!Cools.isEmpty(inWrkMasts) && inWrkMasts.size() >= devpCheckTaskStackOver) { // News.error("" + mark + " - 2" + " - 检测存在1062站点,存在两笔工作中的任务,工作号={}" + wrkMast.getWrkNo()); // continue; // } // } // }else if (wrkMast.getIoType() == 101) { // List<WrkMast> inWrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>() // .in("wrk_sts", 12, 14) // ); // if (!Cools.isEmpty(inWrkMasts) && inWrkMasts.size() >= outNumber) { // News.error("" + mark + " - 4" + " - 检测到全板出库的任务已经到达上线,工作号={}" + wrkMast.getWrkNo()); // continue; // } // } // // 入出库模式判断 // if (devpThread.ioMode != IoModeType.PAKOUT_MODE) { continue; } // if (wrkMast.getStaNo() == 204 && devpThread.ioModeOf2F != IoModeType.PAKOUT_MODE) { // News.infoNoLog(""+mark+" - 2"+" - 4"+" - 入出库模式(此处出库方法,出库模式继续=="+devpThread.ioModeOf2F); // continue; // } // 查询站点详细信息 BasDevp staDetl = basDevpService.selectById(crnStn.getStaNo()); if (staDetl == null) { News.error("" + mark + " - 2" + " - 5" + " - 出库 ===>> 堆垛机站点在数据库不存在, 站点编号={}", crnStn.getStaNo()); News.error("出库 ===>> 堆垛机站点在数据库不存在, 站点编号={}", crnStn.getStaNo()); break; // continue; } //查询在库信息 LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>() .eq("loc_sts", "R") .eq("loc_no", wrkMast.getSourceLocNo())); if (Cools.isEmpty(locMast)) { News.error("出库 ===>> 库位中没有这笔资料", wrkMast.getSourceLocNo()); continue; } //堆垛机接驳站点没有空料架 if(!staProtocol.isEmptyOutType()&&(Cools.isEmpty(wrkMast.getCtnType())||wrkMast.getCtnType()==0)){ //请求wms下发agv搬运空料架到堆垛机接驳站点任务 try { HashMap<String,Object> hashMap=new HashMap<>(); hashMap.put("wrkNo",wrkMast.getWrkNo()); String response = new HttpHandler.Builder() .setUri(wmsUrl) .setPath("/rpc/createAGVMoveTask") .setJson(JSON.toJSONString(wrkMast)) .build() .doPost(); JSONObject jsonObject = JSON.parseObject(response); if (jsonObject.getInteger("code").equals(200)) { wrkMast.setCtnType(1);//已生成AGV搬运空料架任务 wrkMastService.updateById(wrkMast); } else { continue; } } catch (Exception e) { e.printStackTrace(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } } // 判断堆垛机出库站状态 if (staProtocol.isAutoing() && !staProtocol.isLoading() && staDetl.getCanouting() != null && staDetl.getCanouting().equals("Y")) { //根据参数判断是否校验可出信号 // String crnOutVerifyOut = "Y"; // Config crnOutVerifyOutEnableConfig = configService.selectOne(new EntityWrapper<Config>() // .eq("code", "crnOutVerifyOutEnable")); // if (crnOutVerifyOutEnableConfig != null) { // crnOutVerifyOut = crnOutVerifyOutEnableConfig.getValue(); // } // // if (crnOutVerifyOut.equals("Y")) { // if (!staProtocol.isOutEnable()) { // continue; // } // // if (staProtocol.getWorkNo() > 0) { // continue; // } // } if (staProtocol.isAutoing() && !staProtocol.isLoading() && staDetl.getCanouting() != null && staDetl.getCanouting().equals("Y") && staProtocol.getWorkNo() == 0 && staProtocol.isOutEnable() && staProtocol.isEmptyOutType()) { // 命令下发区 -------------------------------------------------------------------------- // 堆垛机控制过滤 @@ -1278,35 +1210,12 @@ break; } // if (crnProtocol.getCrnNo() == 1) { // String turnCrnExecuteCurrentChannel = "Y"; // Config turnCrnExecuteCurrentChannelConfig = configService.selectOne(new EntityWrapper<Config>() // .eq("code", "turnCrnExecuteCurrentChannel") // ); // if (turnCrnExecuteCurrentChannelConfig != null) { // turnCrnExecuteCurrentChannel = turnCrnExecuteCurrentChannelConfig.getValue(); // } // // if (turnCrnExecuteCurrentChannel.equals("Y")) { // //判断堆垛机和当前任务是否处于一个巷道 // if (Utils.getLaneByLocNo(wrkMast.getSourceLocNo()) != crnProtocol.getCrnLane()) { // //判断堆垛机所在巷道是否存在其他任务,如存在则优先执行 // List<WrkMast> currentWrkMasts = wrkMastService.selectLaneWrkMast(crnProtocol.getCrnLane(), false); // if (!currentWrkMasts.isEmpty()) { // continue;//当前堆垛机所在巷道存在任务 // } // } // } // } // 双深库位且浅库位有货,则需先对浅库位进行库位移转 if (Utils.isDeepLoc(slaveProperties, wrkMast.getSourceLocNo())) { News.warnNoLog("" + mark + " - 2" + " - 6" + " - 双深库位且浅库位有货,则需先对浅库位进行库位移转 : 开始执行 任务号={}", wrkMast.getWrkNo()); String shallowLocNo = Utils.getShallowLoc(slaveProperties, wrkMast.getSourceLocNo()); LocMast shallowLoc = locMastService.selectById(shallowLocNo); // O.空库位、Q.拣料/盘点/并板再入库、S.入库预约、X.禁用 直接搬! if (shallowLoc.getLocSts().equals("P") || shallowLoc.getLocSts().equals("R")) { News.warnNoLog("" + mark + " - 2" + " - 7" + " - // O.空库位、Q.拣料/盘点/并板再入库、S.入库预约、X.禁用 直接搬!库位={},库位状态={}", shallowLoc.getLocNo(), shallowLoc.getLocSts()); WrkMast waitWrkMast = wrkMastMapper.selectByLocNo(shallowLocNo); if (null == waitWrkMast) { News.error("{}库位异常,未检索到相应工作档!", shallowLocNo); @@ -1315,7 +1224,7 @@ waitWrkMast.setIoPri(15D); waitWrkMast.setModiTime(new Date()); if (wrkMastMapper.updateById(waitWrkMast) == 0) { News.error("" + mark + " - 2" + " - 8" + " - 调整工作档优先级失败!工作号={}", waitWrkMast.getWrkNo()); News.error("调整工作档优先级失败!工作号={}", waitWrkMast.getWrkNo()); } continue; } else { @@ -1323,31 +1232,20 @@ } } } else if (shallowLoc.getLocSts().equals("F") || shallowLoc.getLocSts().equals("D")) { News.warnNoLog("" + mark + " - 2" + " - 9" + " - // F、D 库位={},库位状态={}", shallowLoc.getLocNo(), shallowLoc.getLocSts()); // WrkMast waitWrkMast = wrkMastMapper.selectByLocNo(shallowLocNo); //2022-08-16 modify,不根据updmk标记移库任务(容易被取消导致堵塞),查询工作档是否存在任务 WrkMast waitWrkMast = wrkMastMapper.selectByLocNo1(shallowLocNo); WrkMast waitWrkMast = wrkMastMapper.selectByLocNo(shallowLocNo); // 此标记避免多次执行移库任务 // if (Cools.isEmpty(wrkMast.getUpdMk()) || "N".equals(wrkMast.getUpdMk()) // || Cools.isEmpty(waitWrkMast)) { if (Cools.isEmpty(waitWrkMast)) { if (moveLocForDeepLoc(slave, crnProtocol, shallowLoc, mark)) { wrkMast.setUpdMk("Y"); // wrkMast.setIoPri(14D); wrkMastMapper.updateById(wrkMast); } // wrkMast.setUpdMk("Y"); // wrkMastMapper.updateById(wrkMast); // // 生成工作档,将浅库位移转到新的库位中 // moveLocForDeepLoc(slave, shallowLoc,mark); if (Cools.isEmpty(wrkMast.getUpdMk()) || "N".equals(wrkMast.getUpdMk()) || Cools.isEmpty(waitWrkMast)) { wrkMast.setUpdMk("Y"); wrkMastMapper.updateById(wrkMast); // 生成工作档,将浅库位移转到新的库位中 moveLocForDeepLoc(slave, shallowLoc); } News.error("{}任务出库失败,浅库位堵塞!浅库位号:{}", wrkMast.getWrkNo(), shallowLocNo); News.error("{}任务出库失败,浅库位堵塞!", wrkMast.getWrkNo()); continue; } else if (shallowLoc.getLocSts().equals("Q") || shallowLoc.getLocSts().equals("S")) { News.warnNoLog("" + mark + " - 2" + " - 10" + " - // Q、S 库位={},库位状态={}", shallowLoc.getLocNo(), shallowLoc.getLocSts()); WrkMast waitWrkMast = wrkMastMapper.selectByLocNo1(shallowLocNo); WrkMast waitWrkMast = wrkMastMapper.selectByLocNo(shallowLocNo); if (null != waitWrkMast && waitWrkMast.getWrkSts() == 4) { News.infoNoLog("" + mark + " - 2" + " - 11" + " - // F、D 工作状态(判断条件为==4)={}", waitWrkMast.getWrkSts()); continue; } } @@ -1359,15 +1257,11 @@ // return; } News.warnNoLog("" + mark + " - 2" + " - 12" + " - 命令下发 : 工作号={},源排={},源列={},源层={},目标排={},目标列={},目标层={}", wrkMast.getWrkNo().shortValue() , sourceSta.getRow1().shortValue(), sourceSta.getBay1().shortValue(), sourceSta.getLev1().shortValue() , crnStn.getRow().shortValue(), crnStn.getBay().shortValue(), crnStn.getLev().shortValue()); // 1.堆垛机开始移动 CrnCommand crnCommand = new CrnCommand(); crnCommand.setCrnNo(slave.getId()); // 堆垛机编号 crnCommand.setTaskNo(wrkMast.getWrkNo().shortValue()); // 工作号 // crnCommand.setAckFinish((short) 0); // 任务完成确认位 crnCommand.setAckFinish((short) 0); // 任务完成确认位 crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE); // 任务模式: 库位移转 crnCommand.setSourcePosX(sourceSta.getRow1().shortValue()); // 源库位排 crnCommand.setSourcePosY(sourceSta.getBay1().shortValue()); // 源库位列 @@ -1375,8 +1269,9 @@ crnCommand.setDestinationPosX(crnStn.getRow().shortValue()); // 目标库位排 crnCommand.setDestinationPosY(crnStn.getBay().shortValue()); // 目标库位列 crnCommand.setDestinationPosZ(crnStn.getLev().shortValue()); // 目标库位层 crnCommand.setBarcode(wrkMast.getBarcode()); if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getCrnNo(), new Task(2, crnCommand))) { News.error("" + mark + " - 2" + " - 13" + " - 堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMast.getCrnNo(), JSON.toJSON(crnCommand)); News.error("堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMast.getCrnNo(), JSON.toJSON(crnCommand)); } else { // 修改工作档状态 11.生成出库ID => 12.吊车出库中 Date now = new Date(); @@ -1384,14 +1279,14 @@ wrkMast.setCrnStrTime(now); wrkMast.setModiTime(now); if (wrkMastMapper.updateById(wrkMast) == 0) { News.error("" + mark + " - 2" + " - 14" + " - 修改工作档状态 11.生成出库ID => 12.吊车出库中 失败!!,工作号={}", wrkMast.getWrkNo()); News.error("修改工作档状态 11.生成出库ID => 12.吊车出库中 失败!!,工作号={}", wrkMast.getWrkNo()); } break; } } } } News.infoNoLog("" + mark + " - 2" + " - 0" + " - 堆垛机入出库作业下发 : 出库执行完毕"); } // /** @@ -1896,9 +1791,9 @@ if (staProtocol.isAutoing() && staProtocol.isInEnable() && staProtocol.isEmptyMk() && (staProtocol.getWorkNo() > 9990 && staProtocol.getWorkNo() <= 9999) && (staProtocol.getWorkNo() ==0) && staProtocol.isPakMk() && staProtocol.getEmptyInType() == 1 // && staProtocol.getEmptyInType() == 1 ) { News.warnNoLog("" + mark + " - 0" + " - 开始执行:空栈板初始化入库,叉车入库站放货"); @@ -1921,6 +1816,11 @@ String errorMsg = "扫码失败,请重试"; MessageQueue.offer(SlaveType.Led, emptyInSta.getLed(), new Task(5, errorMsg)); } continue; } WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("barcode", barcode)); WaitPakin waitPakin = waitPakinMapper.selectOne(new EntityWrapper<WaitPakin>().eq("zpallet", barcode).getEntity()); if (waitPakin != null || wrkMast != null) { continue; } @@ -2469,21 +2369,15 @@ * 因双深库位阻塞,对浅库位进行移转(立即执行版) * tip:同步 */ private synchronized boolean moveLocForDeepLoc(CrnSlave crn, CrnProtocol crnProtocol, LocMast shallowLoc, Integer mark) { private void moveLocForDeepLoc(CrnSlave crn, LocMast shallowLoc) { try { News.warnNoLog("" + mark + "moveLocForDeepLoc" + " - 0" + " - 开始执行:因双深库位阻塞,对浅库位进行移转(立即执行版)"); List<Integer> rows = locMastService.queryDistinctRow(crn.getId()); LocMast loc = null; for (Integer row : rows) { if (Utils.isDeepLoc(slaveProperties, row)) { loc = locMastService.queryFreeLocMast(row, shallowLoc.getLocType1()); if (loc != null) { if (crn.getId() == 1) { if (Utils.getLaneByLocNo(loc.getLocNo()) != crnProtocol.getCrnLane()) { continue; } } if (loc != null) { if (Utils.isDeepLoc(slaveProperties, loc.getLocNo())) { String shallowLocNo = Utils.getShallowLoc(slaveProperties, loc.getLocNo()); LocMast shallowLoc1 = locMastService.selectById(shallowLocNo); @@ -2503,12 +2397,6 @@ loc = locMastService.queryFreeLocMast(row, shallowLoc.getLocType1()); if (null != loc) {//对应深库位非在库状态,不能移库 if (crn.getId() == 1) { if (Utils.getLaneByLocNo(loc.getLocNo()) != crnProtocol.getCrnLane()) { continue; } } String deepLoc = Utils.getDeepLoc(slaveProperties, loc.getLocNo()); LocMast deepLoc1 = locMastService.selectById(deepLoc); if (!deepLoc1.getLocSts().equals("F") && !deepLoc1.getLocSts().equals("D")) { @@ -2524,107 +2412,76 @@ } if (null == loc) { News.error("" + mark + "moveLocForDeepLoc" + " - 1" + " - 双深库位 --- 浅库位阻塞异常! 待移转浅库位:" + shallowLoc.getLocNo()); return false; log.error("双深库位 --- 浅库位阻塞异常! 待移转浅库位:" + shallowLoc.getLocNo()); return; // throw new CoolException("双深库位 --- 浅库位阻塞异常! 待移转浅库位:" + shallowLoc.getLocNo()); } else { String deepLoc2 = Utils.getDeepLoc2(slaveProperties, loc.getLocNo()); if (deepLoc2 != null) { LocMast locnew = locMastService.selectById(deepLoc2); if (locnew != null && locnew.getLocSts().equals("O")) { loc = locnew; } } try { // 获取工作号 int workNo = commonService.getWorkNo(0); // 保存工作档 WrkMast wrkMast = new WrkMast(); wrkMast.setWrkNo(workNo); wrkMast.setIoTime(new Date()); wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID wrkMast.setIoType(11); // 入出库状态: 11.库格移载 wrkMast.setIoPri(13D); wrkMast.setCrnNo(crn.getId()); wrkMast.setSourceLocNo(shallowLoc.getLocNo()); // 源库位 wrkMast.setLocNo(loc.getLocNo()); // 目标库位 // wrkMast.setFullPlt(shallowLoc.getFullPlt()); // 满板 wrkMast.setFullPlt(shallowLoc.getLocSts().equals("D") ? "N" : "Y"); // 满板 wrkMast.setPicking("N"); // 拣料 wrkMast.setExitMk("N"); // 退出 wrkMast.setEmptyMk(shallowLoc.getLocSts().equals("D") ? "Y" : "N"); // 空板 wrkMast.setBarcode(shallowLoc.getBarcode()); // 托盘码 wrkMast.setLinkMis("N"); wrkMast.setAppeTime(new Date()); wrkMast.setModiTime(new Date()); int res = wrkMastMapper.insert(wrkMast); if (res == 0) { News.errorNoLog("" + mark + "moveLocForDeepLoc" + " - 2" + " - 保存工作档失败"); // throw new CoolException("保存工作档失败"); return true; } // 工作档明细保存 if (shallowLoc.getLocSts().equals("F")) { List<LocDetl> locDetls = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("loc_no", shallowLoc.getLocNo())); for (LocDetl locDetl : locDetls) { WrkDetl wrkDetl = new WrkDetl(); wrkDetl.sync(locDetl); wrkDetl.setWrkNo(workNo); wrkDetl.setIoTime(new Date()); wrkDetl.setAnfme(locDetl.getAnfme()); // VersionUtils.setWrkDetl(wrkDetl, locDetl); // 版本控制 wrkDetl.setAppeTime(new Date()); wrkDetl.setModiTime(new Date()); if (!wrkDetlService.insert(wrkDetl)) { News.errorNoLog("" + mark + "moveLocForDeepLoc" + " - 3" + " - 保存工作档明细失败"); // throw new CoolException("保存工作档明细失败"); return true; } } } // 修改源库位状态 if (shallowLoc.getLocSts().equals("D") || shallowLoc.getLocSts().equals("F")) { shallowLoc.setLocSts("R"); // R.出库预约 shallowLoc.setModiTime(new Date()); if (!locMastService.updateById(shallowLoc)) { News.errorNoLog("" + mark + "moveLocForDeepLoc" + " - 4" + " - 更新源库位状态失败"); // throw new CoolException("更新源库位状态失败"); return true; } } else { News.errorNoLog("" + mark + "moveLocForDeepLoc" + " - 5" + " - 源库位出库失败"); // throw new CoolException("源库位出库失败"); return true; } // 修改目标库位状态 if (loc.getLocSts().equals("O")) { loc.setLocSts("S"); // S.入库预约 loc.setModiTime(new Date()); if (!locMastService.updateById(loc)) { News.errorNoLog("" + mark + "moveLocForDeepLoc" + " - 6" + " - 更新目标库位状态失败"); // throw new CoolException("更新目标库位状态失败"); return true; } } else { News.errorNoLog("" + mark + "moveLocForDeepLoc" + " - 7" + " - 移转失败"); // throw new CoolException("移转失败"); return true; } } catch (Exception e) { News.error("" + mark + "moveLocForDeepLoc" + " - 8" + " - 双深库位阻塞,对浅库位进行移转失败", e); } } // 获取工作号 int workNo = commonService.getWorkNo(0); // 保存工作档 WrkMast wrkMast = new WrkMast(); wrkMast.setWrkNo(workNo); wrkMast.setIoTime(new Date()); wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID wrkMast.setIoType(11); // 入出库状态: 11.库格移载 wrkMast.setIoPri(13D); wrkMast.setCrnNo(crn.getId()); wrkMast.setSourceLocNo(shallowLoc.getLocNo()); // 源库位 wrkMast.setLocNo(loc.getLocNo()); // 目标库位 wrkMast.setFullPlt(shallowLoc.getLocSts().equals("F") ? "Y" : "N"); // 满板 wrkMast.setPicking("N"); // 拣料 wrkMast.setExitMk("N"); // 退出 wrkMast.setEmptyMk(shallowLoc.getLocSts().equals("D") ? "Y" : "N"); // 空板 wrkMast.setBarcode(shallowLoc.getBarcode()); // 托盘码 wrkMast.setLinkMis("N"); wrkMast.setAppeTime(new Date()); wrkMast.setModiTime(new Date()); int res = wrkMastMapper.insert(wrkMast); if (res == 0) { throw new CoolException("保存工作档失败"); } // 工作档明细保存 if (shallowLoc.getLocSts().equals("F")) { List<LocDetl> locDetls = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("loc_no", shallowLoc.getLocNo())); for (LocDetl locDetl : locDetls) { WrkDetl wrkDetl = new WrkDetl(); wrkDetl.setWrkNo(workNo); wrkDetl.setIoTime(new Date()); wrkDetl.setAnfme(locDetl.getAnfme()); VersionUtils.setWrkDetl(wrkDetl, locDetl); // 版本控制 wrkDetl.setAppeTime(new Date()); wrkDetl.setModiTime(new Date()); if (!wrkDetlService.insert(wrkDetl)) { throw new CoolException("保存工作档明细失败"); } } } // 修改源库位状态 if (shallowLoc.getLocSts().equals("D") || shallowLoc.getLocSts().equals("F")) { shallowLoc.setLocSts("R"); // R.出库预约 shallowLoc.setModiTime(new Date()); if (!locMastService.updateById(shallowLoc)) { throw new CoolException("更新源库位状态失败"); } } else { throw new CoolException("源库位出库失败"); } // 修改目标库位状态 if (loc.getLocSts().equals("O")) { loc.setLocSts("S"); // S.入库预约 loc.setModiTime(new Date()); if (!locMastService.updateById(loc)) { throw new CoolException("更新目标库位状态失败"); } } else { throw new CoolException("移转失败"); } } catch (Exception e) { News.error("" + mark + "moveLocForDeepLoc" + " - 8" + " - 双深库位阻塞,对浅库位进行移转失败", e); // e.printStackTrace(); // TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); log.error("双深库位阻塞,对浅库位进行移转失败", e); e.printStackTrace(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } return true; } /** @@ -2677,7 +2534,7 @@ wrkMast.setCrnNo(crn.getId()); wrkMast.setSourceLocNo(sourceLocNo); // 源库位 wrkMast.setLocNo(locNo); // 目标库位 wrkMast.setFullPlt("N"); // 满板:Y wrkMast.setFullPlt(sourceLoc.getLocSts().equals("F")?"Y":"N"); // 满板:Y wrkMast.setPicking("N"); // 拣料 wrkMast.setExitMk("N"); // 退出 wrkMast.setEmptyMk(sourceLoc.getLocSts().equals("D") ? "Y" : "N"); // 空板 src/main/java/com/zy/asrs/service/impl/RcsServiceImpl.java
New file @@ -0,0 +1,317 @@ package com.zy.asrs.service.impl; import com.alibaba.excel.util.StringUtils; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.Cools; import com.core.common.R; import com.zy.asrs.entity.*; import com.zy.asrs.enums.RcsRetMethodEnum; import com.zy.asrs.service.RcsService; import com.zy.asrs.service.TaskService; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.SlaveConnection; import com.zy.core.enums.SlaveType; import com.zy.core.model.protocol.StaProtocol; import com.zy.core.thread.SiemensDevpThread; 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 java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ConnectException; import java.net.SocketTimeoutException; import java.net.URL; import java.net.URLConnection; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @Slf4j @Service public class RcsServiceImpl implements RcsService { // 海康RCS地址 @Value("${hik.url}") private String HIK_URL; @Autowired private TaskService taskService; /** * 2.2.1任务执行回馈 * 厂家:海量、华晓 * * @param rcsReporterTask * @return */ @Override public RcsReturn reporterTask(RcsReporterTask rcsReporterTask) { RcsReturn rcsReturn = new RcsReturn(); String robotTaskCode = rcsReporterTask.getRobotTaskCode(); String singleRobotCode = rcsReporterTask.getSingleRobotCode(); String[] split = robotTaskCode.split("-"); robotTaskCode = split[0]; JSONObject values = rcsReporterTask.getExtra().getJSONObject("values"); // start : 任务开始;outbin : 走出储位;end : 任务完成 String method = values.getString("method"); String carrierType = values.getString("carrierType"); String slotCategory = values.getString("slotCategory"); String slotCode = values.getString("slotCode"); EntityWrapper<Task> wrapper = new EntityWrapper<>(); wrapper.eq("task_no", robotTaskCode); Task task = taskService.selectOne(wrapper); if(!Cools.isEmpty(task)){ try { // q3,q8=1 if ("1".equals(carrierType)) { //AGV switch (Objects.requireNonNull(RcsRetMethodEnum.getEnum(method))) { //放货申请 case APPLY_PUT: { Integer sourceStaNo = Integer.valueOf(task.getStaNo()); SiemensDevpThread siemensDevpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1); StaProtocol staProtocol = siemensDevpThread.getStation().get(sourceStaNo).clone(); //wcs反馈rcs继续执行 if (staProtocol != null && !staProtocol.isLoading() && !staProtocol.isEmptyOutType()) { RcsTaskContinue rcsTaskContinue = new RcsTaskContinue(); rcsTaskContinue.setRobotTaskCode(task.getTaskNo()); rcsTaskContinue.setTriggerType("TASK"); rcsTaskContinue.setTriggerCode(task.getTaskNo()); String url =HIK_URL + "api/robot/controller/task/extend/continue"; String response = sendPost(url, JSONObject.toJSONString(rcsTaskContinue)); if (!StringUtils.isEmpty(response) && response.contains("code")){ RcsReturn rcsReturn1 = JSONObject.parseObject(response, RcsReturn.class); if("200".equals(rcsReturn1.getCode())) { //出发PLC站点的扫码器扫码 boolean result = MessageQueue.offer(SlaveType.Devp, 1, new com.zy.core.model.Task(3, staProtocol)); log.info("AGV放货完成,给站点写9991工作号,下发任务:{},站点:{},agv任务号:{}",result,task.getStaNo(),task.getTaskNo()); if (result) { // 返回RCS rcsReturn.setCode("SUCCESS"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); }else { // 返回RCS rcsReturn.setCode("Err_Internal"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); } } } } } break; //放货完成 --》agv已经离开 case TASK_END: { Integer sourceStaNo = Integer.valueOf(task.getStaNo()); SiemensDevpThread siemensDevpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1); StaProtocol staProtocol = siemensDevpThread.getStation().get(sourceStaNo).clone(); //放货完成 --》agv已经离开 --》给PLC站点写9991工作号 if (staProtocol != null && staProtocol.isLoading() && staProtocol.isEmptyOutType() && staProtocol.getWorkNo() ==0) { staProtocol.setWorkNo((short) 9991); staProtocol.setStaNo(Short.valueOf(task.getStaNo())); boolean result = MessageQueue.offer(SlaveType.Devp, 1, new com.zy.core.model.Task(2, staProtocol)); log.info("AGV放货完成,给站点写9991工作号,下发任务:{},站点:{},agv任务号:{}",result,task.getStaNo(),task.getTaskNo()); if(result){ // 更新任务状态等内部逻辑 task.setWrkSts(304L); // 301 任务下发、302 任务执行、303 任务中断、304 任务结束 task.setModiTime(new Date()); taskService.updateById(task); // 返回RCS rcsReturn.setCode("SUCCESS"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); }else { // 返回RCS rcsReturn.setCode("Err_Internal"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); } } } break; //rcs请求wms取货申请 case APPLY_PICK: { Integer sourceStaNo = Integer.valueOf(task.getSourceStaNo()); SiemensDevpThread siemensDevpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1); StaProtocol staProtocol = siemensDevpThread.getStation().get(sourceStaNo).clone(); //判断站点是否有料架和托盘 if (staProtocol != null && staProtocol.isLoading() && staProtocol.isEmptyOutType() && staProtocol.getWorkNo() >0 && staProtocol.getWorkNo() <9990) { RcsTaskContinue rcsTaskContinue = new RcsTaskContinue(); rcsTaskContinue.setRobotTaskCode(task.getTaskNo()); rcsTaskContinue.setTriggerType("TASK"); rcsTaskContinue.setTriggerCode(task.getTaskNo()); String url =HIK_URL + "api/robot/controller/task/extend/continue"; String response = sendPost(url, JSONObject.toJSONString(rcsTaskContinue)); if (!StringUtils.isEmpty(response) && response.contains("code")){ RcsReturn rcsReturn1 = JSONObject.parseObject(response, RcsReturn.class); if("200".equals(rcsReturn1.getCode())) { // 返回RCS rcsReturn.setCode("SUCCESS"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); }else { // 返回RCS rcsReturn.setCode("Err_Internal"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); } } } } break; //rcs取货完成,已退出输送线 case PICK_COMPLETE: { Integer sourceStaNo = Integer.valueOf(task.getSourceStaNo()); SiemensDevpThread siemensDevpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1); StaProtocol staProtocol = siemensDevpThread.getStation().get(sourceStaNo).clone(); //放货完成 --》agv已经离开 --》给PLC站点写9991工作号 if (staProtocol != null && !staProtocol.isLoading() && !staProtocol.isEmptyOutType() && staProtocol.getWorkNo() >0 && staProtocol.getWorkNo() <9990) { staProtocol.setWorkNo((short) 0); staProtocol.setStaNo((short) 0); boolean result = MessageQueue.offer(SlaveType.Devp, 1, new com.zy.core.model.Task(2, staProtocol)); log.info("AGV取货完成,给站点写0工作号,下发任务:{},站点:{},agv任务号:{}",result,task.getStaNo(),task.getTaskNo()); if(result){ // 返回RCS rcsReturn.setCode("SUCCESS"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); }else { // 返回RCS rcsReturn.setCode("Err_Internal"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); } } } break; default: { } break; } } } catch (Exception e) { log.error("RCS反馈任务进度处理异常 - {}", rcsReporterTask, e); rcsReturn.setCode("Err_Internal"); rcsReturn.setMessage("内部处理异常"); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); } } return rcsReturn; } /** * 向指定 URL 发送POST方法的请求 * * @param url 发送请求的 URL * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return 所代表远程资源的响应结果 */ public static String sendPost(String url, String param) { PrintWriter out = null; BufferedReader in = null; StringBuilder result = new StringBuilder(); try { log.info("sendPost - {} - {}", url, param); URL realUrl = new URL(url); URLConnection conn = realUrl.openConnection(); conn.setRequestProperty("Content-Type", "application/json"); conn.setRequestProperty("Content-Length", "<calculated when request is sent>"); conn.setRequestProperty("Host", "<calculated when request is sent>"); conn.setRequestProperty("Accept", "*/*"); conn.setRequestProperty("Accept-Encoding", "gzip, deflate, br"); conn.setRequestProperty("Connection", "keep-alive"); conn.setRequestProperty("X-lr-request-id", String.valueOf(new Date().getTime())); conn.setRequestProperty("X-lr-version", "4.3"); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); conn.setDoOutput(true); conn.setDoInput(true); out = new PrintWriter(conn.getOutputStream()); out.print(param); out.flush(); in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)); String line; while ((line = in.readLine()) != null) { result.append(line); } log.info("recv - {}", result); } catch (ConnectException e) { log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e); } catch (SocketTimeoutException e) { log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e); } catch (IOException e) { log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e); } catch (Exception e) { log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e); } finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { log.error("调用in.close Exception, url=" + url + ",param=" + param, ex); } } return result.toString(); } } src/main/java/com/zy/asrs/service/impl/TaskServiceImpl.java
New file @@ -0,0 +1,23 @@ package com.zy.asrs.service.impl; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.baomidou.mybatisplus.service.impl.ServiceImpl; import com.core.common.Cools; import com.core.common.DateUtils; import com.core.exception.CoolException; import com.zy.asrs.entity.Task; import com.zy.asrs.entity.WaitPakin; import com.zy.asrs.mapper.TaskMapper; import com.zy.asrs.service.TaskService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit; @Service("taskService") public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements TaskService { } src/main/java/com/zy/asrs/utils/VersionUtils.java
@@ -1,6 +1,8 @@ package com.zy.asrs.utils; import com.zy.asrs.entity.LocDetl; import com.zy.asrs.entity.LocMast; import com.zy.asrs.entity.WrkDetl; import com.zy.common.model.LocTypeDto; /** @@ -26,5 +28,17 @@ return true; } public static void setWrkDetl(WrkDetl wrkDetl, LocDetl locDetl) { wrkDetl.setMatnr(locDetl.getMatnr()); // 产品编号 wrkDetl.setMaktx(locDetl.getMaktx()); // 产品描述 wrkDetl.setSpecs(locDetl.getSpecs()); // 规格 wrkDetl.setUnit(locDetl.getUnit()); // 单位 // wrkDetl.setSize(locDetl.getSize()); // 尺寸 wrkDetl.setColor(locDetl.getColor()); // 颜色 wrkDetl.setWeight(locDetl.getWeight()); // 单重 wrkDetl.setZpallet(locDetl.getZpallet()); // 托盘条码 wrkDetl.setAnfme(locDetl.getAnfme());//数量 } } src/main/java/com/zy/common/utils/HikUtils.java
New file @@ -0,0 +1,39 @@ package com.zy.common.utils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.util.HashMap; @Component public class HikUtils { @Value("${zyHikUrl}") private String hikUrl; public void startPic(String ip, String filename) { try { HashMap<String, Object> data = new HashMap<>(); data.put("ip", ip); data.put("filename", filename); String response = new HttpHandler.Builder() .setUri(hikUrl) .setPath("/startPic") .setJson(JSON.toJSONString(data)) .build() .doPost(); JSONObject jsonObject = JSON.parseObject(response); if (jsonObject.getInteger("code").equals(200)) { News.error("请求接口成功!!!url:{};request:{};response:{}", hikUrl + "/startPic", JSON.toJSONString(data), response); } else { News.error("请求接口失败!!!url:{};request:{};response:{}", hikUrl + "/startPic", JSON.toJSONString(data), response); } } catch (Exception e) { e.printStackTrace(); } } } src/main/java/com/zy/core/model/command/CrnCommand.java
@@ -38,6 +38,11 @@ */ private Short taskMode = 0; private String barcode= ""; //火警: 1是火警 private short fireStaut = 0; @JSONField(serialize = false) private CrnTaskModeType taskModeType; src/main/java/com/zy/core/model/protocol/CrnProtocol.java
@@ -29,6 +29,11 @@ */ public Short eStop; private String barcode= ""; //火警: 1是火警 private short fireStaut = 0; /** * 异常码 */ src/main/java/com/zy/core/model/protocol/StaProtocol.java
@@ -79,6 +79,9 @@ //空托入库类型 private Short emptyInType; //空料架 private boolean emptyOutType; public BasDevp toSqlModel(){ BasDevp basDevp = new BasDevp(); basDevp.setDevNo(siteId); @@ -91,6 +94,7 @@ basDevp.setLocType2((short) 0); // 宽窄类型{0:未知,1:窄库位,2:宽库位} basDevp.setLocType3((short) 0); // 轻重类型{0:未知,1:轻库位,2:重库位} basDevp.setLocType1(high != low && low ? (short) 1 : (short) 2); basDevp.setInreq1(emptyOutType?"Y":"N"); return basDevp; } src/main/java/com/zy/core/thread/SiemensDevpThread.java
@@ -44,6 +44,11 @@ private short heartBeatVal = 1; /** * 条码数量 */ private int barcodeSize = 2; /** * 日志采集时间 */ private Long deviceDataLogTime = System.currentTimeMillis(); @@ -53,7 +58,7 @@ }}; public static final ArrayList<Integer> staNos2 = new ArrayList<Integer>() {{ // add(2000);add(2001);add(2002);add(1001);add(1002);add(1003);add(1004);add(1005);add(1006);add(1007); }}; @@ -61,11 +66,11 @@ public static final ArrayList<Integer> barcode1 = new ArrayList<Integer>() {{ add(1); add(2); // add(2); }}; public static final ArrayList<Integer> barcode2 = new ArrayList<Integer>() {{ // add(3); add(2); // add(4); }}; @@ -125,6 +130,9 @@ // 写数据 ID+目标站 case 2: write((StaProtocol)task.getData()); break; case 3: write1((StaProtocol)task.getData()); break; default: break; @@ -197,7 +205,7 @@ // updateIoMode(); ArrayList<Integer> staNos = getStaNo(); int staNoSize = staNos.size(); OperateResultExOne<byte[]> result = siemensS7Net.Read("DB101.0", (short) (staNoSize * 18)); OperateResultExOne<byte[]> result = siemensS7Net.Read("DB101.0", (short) (staNoSize*8)); if (result.IsSuccess) { for (int i = 0; i < staNoSize; i++) { Integer siteId = staNos.get(i); // 站点编号 @@ -207,40 +215,20 @@ staProtocol.setSiteId(siteId); station.put(siteId, staProtocol); } staProtocol.setSiteId(siteId); staProtocol.setWorkNo((short) siemensS7Net.getByteTransform().TransInt32(result.Content, (i * 18))); // 工作号 staProtocol.setStaNo((short) siemensS7Net.getByteTransform().TransInt32(result.Content, (i * 18) + 4)); // 目标站 staProtocol.setWorkNo((short)siemensS7Net.getByteTransform().TransInt32(result.Content, i*8)); // 工作号 short locHeight = siemensS7Net.getByteTransform().TransInt16(result.Content, (i * 18) + 8);//库位高度 if (locHeight == 2) {//high staProtocol.setHigh(true); staProtocol.setLow(false); }else {//low staProtocol.setHigh(false); staProtocol.setLow(true); } staProtocol.setStaNo(siemensS7Net.getByteTransform().TransInt16(result.Content, i*8 + 4)); // 目标站 staProtocol.setError(siemensS7Net.getByteTransform().TransInt16(result.Content, (i * 18) + 10)); // 报警 boolean[] status = siemensS7Net.getByteTransform().TransBool(result.Content, (i * 18) + 12, 1); staProtocol.setAutoing(status[0]); // 自动 staProtocol.setLoading(status[1]); // 有物 staProtocol.setInEnable(status[2]); // 可入 staProtocol.setOutEnable(status[3]);// 可出 staProtocol.setEmptyMk(status[4]); // 空板信号 staProtocol.setFullPlt(status[5]); // 满托盘 boolean[] statusError = siemensS7Net.getByteTransform().TransBool(result.Content, (i * 18) + 13, 1); staProtocol.setFrontError(statusError[0]); // 前超报警 staProtocol.setBackError(statusError[1]); // 后超报警 staProtocol.setHighError(statusError[2]); // 超高报警 staProtocol.setLeftError(statusError[3]);// 左高报警 staProtocol.setRightError(statusError[4]); // 右高报警 staProtocol.setWeightError(statusError[5]); // 超重报警 staProtocol.setBarcodeError(statusError[6]); // 扫码报警 short emptyInType = siemensS7Net.getByteTransform().TransInt16(result.Content, (i * 18) + 14);//预留1-空托入库类型,1:立库方向 2:产线方向 staProtocol.setEmptyInType(emptyInType); boolean[] status = siemensS7Net.getByteTransform().TransBool(result.Content, i*8 + 6, 2); staProtocol.setAutoing(status[0]); // 自动 staProtocol.setLoading(status[1]); // 有物 staProtocol.setInEnable(status[2]); // 可入 staProtocol.setOutEnable(status[3]); // 可出 staProtocol.setEmptyMk(status[4]); // 空板信号 staProtocol.setFullPlt(status[5]); // 满托盘 staProtocol.setHigh(status[6]); // 高库位 staProtocol.setLow(status[7]); // 低库位 staProtocol.setEmptyOutType(status[8]); //空料架 if (!staProtocol.isPakMk() && !staProtocol.isLoading()) { staProtocol.setPakMk(true); @@ -248,40 +236,57 @@ } } //条码扫描器 Thread.sleep(200); ArrayList<Integer> barcodeList = getBarcode(); int barcodeSize = barcodeList.size(); OperateResultExOne<byte[]> result2 = siemensS7Net.Read("DB103.0", (short) (barcodeSize * 8)); if (result2.IsSuccess) { for (int i = 0; i < barcodeSize; i++) { String barcode = siemensS7Net.getByteTransform().TransString(result2.Content, i * 8, 8, "UTF-8"); Integer barcodeId = barcodeList.get(i); BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, barcodeId); if(!Cools.isEmpty(barcodeThread) && !barcodeThread.getBarcode().equals(barcode)){ barcodeThread.setBarcode(barcode); } //外形检测 Integer[] arr={401,402}; OperateResultExOne<byte[]> resultErr1 = siemensS7Net.Read("DB101.700.0", (short) (arr.length*6)); for (int i = 0; i < arr.length; i++) { StaProtocol staProtocol1 = station.get(arr[i]); if(resultErr1.IsSuccess){ boolean[] status1 = siemensS7Net.getByteTransform().TransBool(resultErr1.Content, i*6, 1); staProtocol1.setFrontError(status1[0]); staProtocol1.setBackError(status1[1]); staProtocol1.setHighError(status1[2]); staProtocol1.setLeftError(status1[3]); staProtocol1.setRightError(status1[4]); staProtocol1.setWeightError(status1[5]); staProtocol1.setBarcodeError(status1[6]); } } if (System.currentTimeMillis() - deviceDataLogTime > 1000 * 1) { //采集时间超过5s,保存一次数据记录 //保存数据记录 DeviceDataLogService deviceDataLogService = SpringUtils.getBean(DeviceDataLogService.class); DeviceDataLog deviceDataLog = new DeviceDataLog(); deviceDataLog.setOriginData(Base64.getEncoder().encodeToString(result.Content)); deviceDataLog.setWcsData(JSON.toJSONString(station)); deviceDataLog.setType("devp"); deviceDataLog.setDeviceNo(slave.getId()); deviceDataLog.setCreateTime(new Date()); deviceDataLogService.insert(deviceDataLog); //更新采集时间 deviceDataLogTime = System.currentTimeMillis(); Thread.sleep(200); if(slave.getId()==1) { OperateResultExOne<byte[]> result2 = siemensS7Net.Read("DB101.600.0", (short) (barcodeSize * 8)); if (result2.IsSuccess) { for (int i = 0; i < barcodeSize; i++) { String barcode = siemensS7Net.getByteTransform().TransString(result2.Content, i * 8, 8, "UTF-8"); BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, i + 1); if (!Cools.isEmpty(barcodeThread) && !barcodeThread.getBarcode().equals(barcode)) { barcodeThread.setBarcode(barcode); } } } } if (result.IsSuccess) { if (System.currentTimeMillis() - deviceDataLogTime > 1000 * 1) { //采集时间超过5s,保存一次数据记录 //保存数据记录 DeviceDataLogService deviceDataLogService = SpringUtils.getBean(DeviceDataLogService.class); DeviceDataLog deviceDataLog = new DeviceDataLog(); deviceDataLog.setOriginData(Base64.getEncoder().encodeToString(result.Content)); deviceDataLog.setWcsData(JSON.toJSONString(station)); deviceDataLog.setType("devp"); deviceDataLog.setDeviceNo(slave.getId()); deviceDataLog.setCreateTime(new Date()); deviceDataLogService.insert(deviceDataLog); if (result.IsSuccess && result2.IsSuccess) { //更新采集时间 deviceDataLogTime = System.currentTimeMillis(); } } if (result.IsSuccess) { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId())); // 根据实时信息更新数据库 @@ -317,57 +322,47 @@ } ArrayList<Integer> staNos = getStaNo(); int index = staNos.indexOf(staProtocol.getSiteId()); int[] array = new int[3]; array[0] = staProtocol.getWorkNo().intValue(); array[1] = staProtocol.getStaNo().intValue(); array[2] = staProtocol.getPalletSize().intValue(); short[] array = new short[2]; OperateResult writeResult1 = siemensS7Net.Write("DB100." + index*6, staProtocol.getWorkNo().intValue()); // 工作号 OperateResult writeResult2 = siemensS7Net.Write("DB100." + (index*6+4), staProtocol.getStaNo()); // 目标站 OperateResult write = siemensS7Net.Write("DB102." + index * 16, array); // OperateResult write = siemensS7Net.Write("DB100.0" + index*4, staProtocol.getWorkNo()); // 工作号 // Thread.sleep(500); // OperateResult write1 = siemensS7Net.Write("DB100.2" + index*4+2, staProtocol.getStaNo()); // 目标站 // OperateResult write = null; // OperateResult write1 = null; // //任务下发次数 // int writeCount = 0; // do { // write = siemensS7Net.Write("DB100." + index*2, staProtocol.getWorkNo()); // 工作号 // Thread.sleep(500); // write1 = siemensS7Net.Write("DB101." + index*2, staProtocol.getStaNo()); // 目标站 // if(write.IsSuccess || write1.IsSuccess){ // Thread.sleep(200); // OperateResultExOne<byte[]> readResult = siemensS7Net.Read("DB100." + index*2, (short) 2); // OperateResultExOne<byte[]> readResult1 = siemensS7Net.Read("DB101." + index*2, (short) 2); // if(readResult.IsSuccess && readResult1.IsSuccess){ // short workNo = siemensS7Net.getByteTransform().TransInt16(readResult.Content, 0); // short staNo = siemensS7Net.getByteTransform().TransInt16(readResult1.Content, 0); // if(staProtocol.getWorkNo().equals(workNo) && staProtocol.getStaNo().equals(staNo)){ // //任务命令写入成功 // log.info("写入输送线命令后返回成功,并且回读成功。输送线plc编号={},{},写入次数={}", slave.getId(), JSON.toJSON(staProtocol), writeCount); // break; // } else {//返回结果是成功了,但是真实值不相同 // writeCount++; // log.error("写入输送线命令后返回成功,但是读取任务值不一致。输送线plc编号={},{},写入次数={}", slave.getId(), JSON.toJSON(staProtocol), writeCount); // } // } else { // writeCount++; // log.error("写入输送线命令后读取失败。输送线plc编号={},站点数据={},写入次数={}", slave.getId(), JSON.toJSON(staProtocol), writeCount); // } // } // else { // writeCount++; // log.error("写入输送线命令后读取失败。输送线plc编号={},站点数据={},写入次数={}", slave.getId(), JSON.toJSON(staProtocol), writeCount); // } // }while (writeCount<5); if (!write.IsSuccess) { if (!writeResult1.IsSuccess&&!writeResult2.IsSuccess) { staProtocol = station.get(staProtocol.getSiteId()); if (staProtocol.getWorkNo() == 0 && staProtocol.getStaNo() ==0) { staProtocol.setPakMk(true); } OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(staProtocol))); News.error("SiemensDevp"+" - 4"+" - 写入输送线站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(staProtocol)); log.error("写入输送线站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(staProtocol)); } else { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】 输送线命令下发 [id:{1}] >>>>> {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(staProtocol))); News.info("SiemensDevp"+" - 5"+" - 输送线命令下发 [id:{}] >>>>> 命令下发: {}", slave.getId(), JSON.toJSON(staProtocol)); log.info("输送线命令下发 [id:{}] >>>>> 命令下发: {}", slave.getId(), JSON.toJSON(staProtocol)); } } /** * 扫码器触发 */ private void write1(StaProtocol staProtocol) throws InterruptedException { if (null == staProtocol) { return; } ArrayList<Integer> staNos = getStaNo(); int index = staNos.indexOf(staProtocol.getSiteId()); if(staProtocol.getSiteId() == 307){ index = 0; } OperateResult writeResult1 = siemensS7Net.Write("DB100.500" + index, 1); // 扫码器触发 if (!writeResult1.IsSuccess) { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(staProtocol))); log.error("写入输送线站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(staProtocol)); } else { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】 输送线命令下发 [id:{1}] >>>>> {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(staProtocol))); log.info("输送线命令下发 [id:{}] >>>>> 命令下发: {}", slave.getId(), JSON.toJSON(staProtocol)); } } src/main/resources/application.yml
@@ -1,5 +1,5 @@ server: port: 9093 port: 9094 servlet: context-path: /@pom.build.finalName@ @@ -8,11 +8,13 @@ name: @pom.build.finalName@ datasource: driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver url: jdbc:sqlserver://127.0.0.1:1433;databasename=jxtlfasrs-yclk url: jdbc:sqlserver://127.0.0.1:1433;databasename=jnejc-hkwms username: sa password: sa@123 mvc: static-path-pattern: /** zyHikUrl: 10.10.10.200:9091/hik # redis: # host: localhost # port: 6379 @@ -34,7 +36,12 @@ enable: false wms: url: 127.0.0.1:8080/wms url: 127.0.0.1:8084/hkwms #海康对接 hik: switch: false url: http://172.26.11.98:80/rcs/rtas/ # 下位机配置 wcs-slave: @@ -55,7 +62,7 @@ # 堆垛机1 crn[0]: id: 1 ip: 172.26.4.132 ip: 172.26.4.131 port: 102 rack: 0 slot: 0 @@ -93,7 +100,7 @@ # 输送线1 devp[0]: id: 1 ip: 172.17.60.100 ip: 172.26.4.141 port: 102 rack: 0 slot: 0 @@ -183,14 +190,14 @@ # LED1 led[0]: id: 1 ip: 127.0.0.1 ip: 172.26.4.211 port: 5005 devpPlcId: ${wcs-slave.devp[0].id} staArr: 401 # LED2 led[1]: id: 2 ip: 172.17.60.183 ip: 172.26.4.212 port: 5005 devpPlcId: ${wcs-slave.devp[0].id} staArr: 402 src/main/resources/mapper/LocMastMapper.xml
@@ -34,6 +34,7 @@ <result column="mk" property="mk" /> <result column="barcode" property="barcode" /> <result column="ctn_no" property="ctnNo" /> <result column="pic" property="pic" /> </resultMap> src/main/resources/mapper/TaskMapper.xml
New file @@ -0,0 +1,11 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zy.asrs.mapper.TaskMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.zy.asrs.entity.Task"> <id column="id" property="id" /> <result column="task_type" property="taskType" /> </resultMap> </mapper> src/main/resources/mapper/WrkMastMapper.xml
@@ -59,6 +59,7 @@ <!-- <result column="Pdc_type" property="PdcType" />--> <result column="ctn_no" property="ctnNo" /> <result column="full_plt" property="fullPlt" /> <result column="pic" property="pic" /> </resultMap>