package com.zy.asrs.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.core.common.DateUtils; import com.core.exception.CoolException; import com.zy.asrs.controller.requestParam.StationRequestParam; import com.zy.asrs.controller.vo.OpenBusSubmitParam; import com.zy.asrs.controller.vo.StationStatus; import com.zy.asrs.controller.vo.TaskDto; import com.zy.asrs.entity.Job; import com.zy.asrs.enums.WorkNoTypeType; import com.zy.asrs.mapper.JobMapper; import com.zy.asrs.service.CtuMainService; import com.zy.asrs.service.WrkLastnoService; import com.zy.common.utils.HttpHandler; import com.zy.common.utils.News; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.SlaveConnection; import com.zy.core.enums.SlaveType; import com.zy.core.model.DevpSlave; import com.zy.core.model.Task; import com.zy.core.model.protocol.StaProtocol; import com.zy.core.properties.SlaveProperties; import com.zy.core.thread.SiemensDevpThread; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit; /** * 立体仓库WCS系统主流程业务 * Created by vincent on 2020/8/6 */ @Slf4j @Service("ctuMainService") @Transactional @Data public class CtuMainServiceImpl implements CtuMainService { public static final long COMMAND_TIMEOUT = 5 * 1000; public static final int LOG_STEP = 1; @Value("${ctu.url}") private String ctuUrl; @Value("${ctu.station}") private String station; @Value("${ctu.sendTask}") private String sendTask; @Autowired private SlaveProperties slaveProperties; @Autowired private WrkLastnoService wrkLastnoService; @Autowired private JobMapper jobMapper; /** * 出库的时候,设备上走 */ @Transactional public synchronized void out(Integer mark) { try { // 根据输送线plc遍历 for (DevpSlave devp : slaveProperties.getDevp()) { // 遍历出库口 for (DevpSlave.Sta releaseSta : devp.getReleaseSta()) { // 获取入库站信息 SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId()); StaProtocol staProtocol = devpThread.getStation().get(releaseSta.getStaNo()); if (staProtocol == null) { continue; } else { staProtocol = staProtocol.clone(); } // 判断是否满足条件 if (!staProtocol.isLoading()) { continue; } //&& staProtocol.isOutEnable() if (staProtocol.isAutoing() && staProtocol.getWorkNo() == 0) { String seqNum = checkStationStatus(releaseSta.getStaNo()); if (seqNum != null) { Job jobBySeqNum = jobMapper.getJobBySeqNum(seqNum); if (jobBySeqNum == null) { int workNo = wrkLastnoService.nextWorkNo(WorkNoTypeType.WORK_NO_TYPE.type); // 下发移动 且 下发plc命令 staProtocol.setWorkNo(workNo); staProtocol.setStaNo(releaseSta.getTargetSta()); Job job = new Job(); job.setSeqNum(seqNum); job.setJobNo(workNo); job.setJobSts(2); if (jobMapper.insert(job) == 0) { throw new CoolException("插入输送线任务失败," + jobBySeqNum + " - " + workNo); } devpThread.setPakMk(staProtocol.getSiteId(), false); boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol)); if (result) { log.info("输送线下发:{},{}", staProtocol.getWorkNo(), releaseSta.getTargetSta()); } else { News.error("" + (mark + LOG_STEP) + " - 发布命令至输送线队列失败!!! [plc编号:{}]", devp.getId()); } } } else { News.errorNoLog("" + (mark + LOG_STEP) + " - 站点信息不符合入库条件!!!" + " 调用RCS检验未通过,站点:" + staProtocol.getSiteId()); } } else { News.errorNoLog("" + (mark + LOG_STEP) + " - 站点信息不符合入库条件!!!" + " 自动信号:" + staProtocol.isLoading() + "、可入信号:" + staProtocol.isInEnable() + "、空板信号:" + staProtocol.isEmptyMk() + "、工作号:" + staProtocol.getWorkNo() + "、锁定标记" + staProtocol.isPakMk()); } } } } catch (Exception e) { e.printStackTrace(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } } /** * 从拣料站到入库站(CTU取货站) */ @Transactional public synchronized void fake(Integer mark) { try { // 根据输送线plc遍历 SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1); StaProtocol staProtocol = devpThread.getStation().get(1004); if (staProtocol == null) { return; } else { staProtocol = staProtocol.clone(); } // 判断是否满足条件 if (!staProtocol.isLoading()) { return; } if (staProtocol.getWorkNo() > 0 && staProtocol.isAutoing()) { Job jobByWorkNo = jobMapper.getJobByJobNo(staProtocol.getWorkNo()); if (jobByWorkNo != null && jobByWorkNo.getJobSts() == 1) { staProtocol.setStaNo(1006); boolean result = MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocol)); if (result) { jobByWorkNo.setJobSts(3); jobByWorkNo.setMemo("模拟按按钮"); jobMapper.updateById(jobByWorkNo); log.info("入库输送线下发:{},{}", staProtocol.getWorkNo(), 1006); } } } } catch (Exception e) { e.printStackTrace(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } } public synchronized void clear(Integer mark) { try { // 根据输送线plc遍历 for (DevpSlave devp : slaveProperties.getDevp()) { // 遍历等待ctu取货站 for (DevpSlave.Sta takeSta : devp.getTakeSta()) { // 根据输送线plc遍历 SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId()); StaProtocol staProtocol = devpThread.getStation().get(takeSta.getStaNo()); if (staProtocol == null) { return; } else { staProtocol = staProtocol.clone(); } // 判断是否满足条件 if (staProtocol.isLoading()) { return; } if (staProtocol.getWorkNo() > 0 && staProtocol.isAutoing()) { Job job = jobMapper.getJobByJobNo(staProtocol.getWorkNo()); if (job != null && job.getJobSts() >= 5) { staProtocol.setWorkNo(0); staProtocol.setStaNo(0); boolean result = MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocol)); if (result) { log.info("" + (mark + LOG_STEP) + "站点清空失败:{},{}", takeSta.getStaNo(), staProtocol.getWorkNo()); } } } } } } catch (Exception e) { e.printStackTrace(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } } @Transactional public synchronized void waitTake(Integer mark) { try { // 根据输送线plc遍历 for (DevpSlave devp : slaveProperties.getDevp()) { // 遍历入库口 for (DevpSlave.Sta inSta : devp.getInSta()) { // 根据输送线plc遍历 SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId()); StaProtocol staProtocol = devpThread.getStation().get(inSta.getStaNo()); if (staProtocol == null) { return; } else { staProtocol = staProtocol.clone(); } // 判断是否满足条件 if (!staProtocol.isLoading()) { return; } if (staProtocol.getWorkNo() > 0 && staProtocol.isAutoing()) { StaProtocol targetStaProtocol = devpThread.getStation().get(inSta.getTargetSta()); if (targetStaProtocol.getWorkNo() == 0 && targetStaProtocol.isAutoing() && !targetStaProtocol.isLoading()) { Job job = jobMapper.getJobByJobNoAndJobSts(staProtocol.getWorkNo(), 2); if (job != null) { staProtocol.setWorkNo(staProtocol.getWorkNo()); staProtocol.setStaNo(inSta.getTargetSta()); boolean result = MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocol)); if (result) { job.setJobSts(4); job.setInTime(new Date()); if (jobMapper.updateById(job) == 0) { throw new CoolException("更新输送线任务失败," + " - " + staProtocol.getWorkNo()); } log.info("" + (mark + LOG_STEP) + "入库前进:{},{}", staProtocol.getWorkNo(), inSta.getTargetSta()); } } else { // 模拟操作逻辑 } } } } } } catch (Exception e) { e.printStackTrace(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } } @Transactional public synchronized void createTake(Integer mark) { try { // 根据输送线plc遍历 for (DevpSlave devp : slaveProperties.getDevp()) { // 遍历入库口 for (DevpSlave.Sta inSta : devp.getInSta()) { // 根据输送线plc遍历 SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId()); StaProtocol staProtocol = devpThread.getStation().get(inSta.getTargetSta()); if (staProtocol == null) { return; } else { staProtocol = staProtocol.clone(); } // 判断是否满足条件 if (!staProtocol.isLoading()) { return; } if (staProtocol.getWorkNo() > 0 && staProtocol.isAutoing()) { Job job = jobMapper.getJobByJobNo(staProtocol.getWorkNo()); if (job != null && job.getJobSts() == 4) { job.setJobSts(5); job.setRcsTime(new Date()); jobMapper.updateById(job); if (!fakeWms(staProtocol)) { throw new CoolException("任务发送给RCS失败," + job.getSeqNum() + " - " + job.getSeqNum()); } } } } } } catch (Exception e) { e.printStackTrace(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } } public boolean fakeWms(StaProtocol staProtocol) { OpenBusSubmitParam openBusSubmitParam = new OpenBusSubmitParam(); openBusSubmitParam.setBatch(DateUtils.convert(new Date())); List taskList = new ArrayList<>(); TaskDto taskDto = new TaskDto(); taskDto.setSeqNum("SSX-RK" + staProtocol.getWorkNo()); taskDto.setOriSta("1007"); taskDto.setPriority(9527); taskList.add(taskDto); openBusSubmitParam.setTaskList(taskList); return sendTask(openBusSubmitParam, staProtocol); } @Transactional public boolean sendTask(OpenBusSubmitParam openBusSubmitParam, StaProtocol staProtocol) { String response = ""; try { response = new HttpHandler.Builder() .setUri(ctuUrl) .setPath(sendTask) .setTimeout(1200, TimeUnit.SECONDS) .setJson(JSON.toJSONString(openBusSubmitParam)) .build() .doPost(); JSONObject jsonObject = JSON.parseObject(response); if (jsonObject.getInteger("code").equals(200)) { log.info("下发任务返回数据:{}", response); return true; } } catch (Exception e) { log.error("请求接口失败!!!url:{};request:{};response:{}", ctuUrl + sendTask, JSON.toJSONString(openBusSubmitParam), response); } return false; } /** * 检查站点状态 * * @param staNo 站点编号 * @return 站点是否可通行 */ private String checkStationStatus(Integer staNo) { StationRequestParam stationRequestParam = new StationRequestParam(); List staNos = new ArrayList<>(); staNos.add(staNo + ""); stationRequestParam.setStaNos(staNos); String response = ""; try { response = new HttpHandler.Builder() .setUri(ctuUrl) .setPath(station) .setTimeout(1200, TimeUnit.SECONDS) .setJson(JSON.toJSONString(stationRequestParam)) .build() .doPost(); JSONObject jsonObject = JSON.parseObject(response); if (jsonObject.getInteger("code").equals(200)) { log.info("RCS返回数据:{}", response); JSONArray data = jsonObject.getJSONArray("data"); List stationStatuses = JSONArray.parseArray(data.toString(), StationStatus.class); for (StationStatus object : stationStatuses) { if (object.getStaNo().equals(staNo + "")) { if (object.getConveyable()) { return object.getSeqNum() == null ? System.currentTimeMillis() + "" : object.getSeqNum(); } else { log.info("站点:{}状态不对", staNo); return null; } } } log.info("未返回站点状态:{}", staNo); } else { log.error("调用下发任务接口报错,响应码:{},响应内容:{}", jsonObject.getInteger("code"), response); throw new CoolException("调用下发任务接口报错,响应码:" + jsonObject.getInteger("code")); } } catch (CoolException e) { log.error("调用站点状态接口异常", e); throw e; } catch (Exception e) { log.error("检查站点状态失败,站点编号:{}", staNo, e); } return null; } }