| | |
| | | stationResponseParam = new StationResponseParam(); |
| | | stationResponseParam.setStaNo(staNo); |
| | | stationResponseParam.setOccupied(staProtocol.isLoading()); |
| | | stationResponseParam.setInEnable((staProtocol.isInEnable() && staProtocol.getWorkNo() == 0 ? true : false)); |
| | | stationResponseParam.setOutEnable((staProtocol.isOutEnable() ? true : false)); |
| | | stationResponseParam.setInEnable((staProtocol.getAllowPut())); |
| | | stationResponseParam.setOutEnable((staProtocol.getAllowTake())); |
| | | stationResponseParam.setOnline(staProtocol.isAutoing()); |
| | | list.add(stationResponseParam); |
| | | } |
| | |
| | | package com.zy.acs.conveyor.core.constant; |
| | | |
| | | public class RedisConveyorConstant { |
| | | |
| | | //输送线任务标识 |
| | | public static final String CONVEYOR_TASK_FLAG = "CONVEYOR_TASK_FLAG"; |
| | | //输送线安全交互标识 |
| | | public static final String CONVEYOR_SAFE_FLAG = "CONVEYOR_SAFE_FLAG"; |
| | | } |
| New file |
| | |
| | | package com.zy.acs.conveyor.core.constant; |
| | | |
| | | public enum SafeSignalField { |
| | | |
| | | SAFE_SIGNAL_TO_CONVEYOR("DB7", 4, 4, 8), |
| | | SAFE_SIGNAL_FROM_CONVEYOR("DB7", 40, 4, 8), |
| | | |
| | | ; |
| | | |
| | | private final String addressPattern; |
| | | private final int offset; |
| | | private final int byteLength; |
| | | private final int arrLength; |
| | | |
| | | SafeSignalField(String addressPattern, int offset, int byteLength, int arrLength) { |
| | | this.addressPattern = addressPattern; |
| | | this.offset = offset; |
| | | this.byteLength = byteLength; |
| | | this.arrLength = arrLength; |
| | | } |
| | | |
| | | public String getAddressPattern() { |
| | | return addressPattern; |
| | | } |
| | | |
| | | public int getOffset() { |
| | | return offset; |
| | | } |
| | | |
| | | public int getByteLength() { |
| | | return byteLength; |
| | | } |
| | | |
| | | public int getArrLength() { |
| | | return arrLength; |
| | | } |
| | | |
| | | /** |
| | | * 根据 DB 块编号和站点偏移生成具体地址 |
| | | * |
| | | * @return PLC4X 地址字符串,如 "DB100.DBD0" |
| | | */ |
| | | public String buildAddress() { |
| | | return addressPattern + PlcConstant.ADDRESS_CONCATENATION + offset; |
| | | } |
| | | } |
| | |
| | | */ |
| | | public enum TaskField { |
| | | ALL("DB13", 48, 48), |
| | | TASK_NUMBER("DB13", 0, 4), |
| | | START_STATION("DB13", 4, 2), |
| | | DEST_STATION("DB13", 6, 2), |
| | | DIRECTION("DB13", 8, 2), |
| | | ROUTE_NUMBER("DB13", 10, 2); |
| | | TASK_NUMBER("DB13", 12, 4), |
| | | START_STATION("DB13", 16, 2), |
| | | DEST_STATION("DB13", 18, 2), |
| | | DIRECTION("DB13", 20, 2), |
| | | ROUTE_NUMBER("DB13", 22, 2); |
| | | |
| | | private final String addressPattern; |
| | | private final int offset; |
| | |
| | | public enum ConveyorStateType { |
| | | //出库设备上走 |
| | | OUTBOUND(2), |
| | | //模拟用户 |
| | | FAKEUSER(3), |
| | | //启动入库 |
| | | STARTUP(3), |
| | | //入库申请 |
| | | APPLYLOC(4), |
| | | //入库设备上走 |
| New file |
| | |
| | | package com.zy.acs.conveyor.core.listen; |
| | | |
| | | import com.zy.acs.common.utils.RedisSupport; |
| | | import com.zy.acs.conveyor.core.constant.RedisConveyorConstant; |
| | | import com.zy.acs.conveyor.core.model.StaProtocol; |
| | | import com.zy.acs.conveyor.core.service.Snap7Service; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.context.event.ApplicationReadyEvent; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.annotation.PreDestroy; |
| | | |
| | | /** |
| | | * 读取redis写入plc |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class DevpSafeDataSubscriber { |
| | | |
| | | private Thread thread; |
| | | |
| | | private final RedisSupport redis = RedisSupport.defaultRedisSupport; |
| | | |
| | | @Autowired |
| | | private Snap7Service snap7Service; |
| | | |
| | | @EventListener(ApplicationReadyEvent.class) |
| | | private void start() { |
| | | thread = new Thread(() -> { |
| | | while (!Thread.currentThread().isInterrupted()) { |
| | | try { |
| | | // 间隔 |
| | | Thread.sleep(20); |
| | | |
| | | StaProtocol protocol = redis.pop(RedisConveyorConstant.CONVEYOR_SAFE_FLAG); |
| | | if (null != protocol) { |
| | | |
| | | snap7Service.writeSafe(protocol); |
| | | } |
| | | |
| | | } catch (Exception ignore) { |
| | | } |
| | | } |
| | | }); |
| | | thread.start(); |
| | | } |
| | | |
| | | @PreDestroy |
| | | public void shutDown() { |
| | | if (thread != null) thread.interrupt(); |
| | | } |
| | | |
| | | |
| | | } |
| New file |
| | |
| | | package com.zy.acs.conveyor.core.model; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | @Data |
| | | public class SafeSignal implements Serializable { |
| | | |
| | | private Integer index; |
| | | |
| | | private Boolean flag; |
| | | |
| | | public SafeSignal(Integer index, Boolean flag) { |
| | | this.index = index; |
| | | this.flag = flag; |
| | | } |
| | | } |
| | |
| | | // 有物 |
| | | private boolean loading; |
| | | |
| | | // 可入 |
| | | // 需求入 |
| | | private boolean inEnable; |
| | | |
| | | // 可出 |
| | | // 需求出 |
| | | private boolean outEnable; |
| | | |
| | | // 空板信号 |
| | |
| | | |
| | | // 低 |
| | | private boolean low; |
| | | |
| | | // 中 |
| | | private boolean mid; |
| | | |
| | | // 启动入库 |
| | | private boolean startup; |
| | | |
| | | // 中途任务申请 |
| | | private boolean segApply; |
| | | |
| | | // 入库异常 |
| | | private boolean applyErr; |
| | | |
| | | //条码 |
| | | private String barcode; |
| | |
| | | |
| | | private Boolean upcontactErr = false; //顶升电机接触器故障 |
| | | |
| | | // 安全交互 ------------------------------------------------------------------------ |
| | | // ctu或agv写给输送线的 |
| | | // ctu申请放 |
| | | private Boolean applyPut = false; |
| | | |
| | | // ctu申请取 |
| | | private Boolean applyTake = false; |
| | | |
| | | // ctu取完成 |
| | | private Boolean putComplete = false; |
| | | |
| | | // ctu放完成 |
| | | private Boolean takeComplete = false; |
| | | |
| | | // 禁止运行 |
| | | private Boolean stop = false; |
| | | |
| | | |
| | | // 输送线写给ctu或agv |
| | | // 心跳 |
| | | private Boolean heartbeat = false; |
| | | |
| | | // 允许取 |
| | | private Boolean allowTake = false; |
| | | |
| | | // 允许放 |
| | | private Boolean allowPut = false; |
| | | |
| | | // 接货完成 |
| | | private Boolean inComplete = false; |
| | | |
| | | // 出货完成 |
| | | private Boolean outComplete = false; |
| | | |
| | | private SafeSignal safeSignal; |
| | | |
| | | |
| | | public Boolean isErr() { |
| | | if (frontErr || backErr || highErr || leftErr || rightErr || weightErr || barcodeErr) { |
| | | return true; |
| | |
| | | package com.zy.acs.conveyor.core.operation.handler; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.zy.acs.common.utils.News; |
| | | import com.zy.acs.common.utils.RedisSupport; |
| | | import com.zy.acs.conveyor.controller.vo.ApplyInDto; |
| | |
| | | staProtocol = staProtocol.clone(); |
| | | } |
| | | // 判断是否满足条件 |
| | | if (!staProtocol.isLoading()) { |
| | | if (staProtocol.isInEnable()) { |
| | | continue; |
| | | } |
| | | if (staProtocol.getWorkNo() > 0 && staProtocol.isAutoing()) { |
| | | if (!staProtocol.isLoading()) { |
| | | News.error("{}:站点:{},无物", config.getMark(), staProtocol.getSiteId()); |
| | | continue; |
| | | } |
| | | if (!staProtocol.isAutoing()) { |
| | | News.error("{}:站点:{},非自动", config.getMark(), staProtocol.getSiteId()); |
| | | continue; |
| | | } |
| | | String barcode = staProtocol.getBarcode(); |
| | | if (Cools.isEmpty(barcode)) { |
| | | News.error("站点:{},未扫到码值:{}", staProtocol.getSiteId(), barcode); |
| | | return; |
| | | continue; |
| | | } |
| | | // 9991是空板,9992是满板 |
| | | if (staProtocol.getWorkNo() >= 9991 && staProtocol.getWorkNo() <= 9992) { |
| | | Job job = jobService.getJobByBarcode(barcode); |
| | | // 申请入库 |
| | | if (job == null || (job != null && job.getJobSts() == ConveyorStateType.CLEARSIGNAL.getStatus())) { |
| | | if (job == null) { |
| | | News.error("{}:站点:{},找不到任务", config.getMark(), staProtocol.getSiteId()); |
| | | continue; |
| | | } |
| | | if (job.getJobSts() != ConveyorStateType.STARTUP.getStatus()) { |
| | | if (job.getJobSts() == ConveyorStateType.INBOUND.getStatus()){ |
| | | continue; |
| | | } |
| | | News.error("{}:站点:{},任务状态不对,{}", config.getMark(), staProtocol.getSiteId(), JSON.toJSON(job)); |
| | | continue; |
| | | } |
| | | |
| | | ApplyInRepsonseDto locOfWms = wmsMainService.getLocOfWms(applyIn(barcode, inSta.getStaNo() + "", staProtocol)); |
| | | if (locOfWms != null) { |
| | | Integer workNo = getWorkNo(); |
| | |
| | | } |
| | | } else { |
| | | News.error("WMS未返回库位信息,条码:{},站点:{}", barcode, inSta.getStaNo()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | package com.zy.acs.conveyor.core.operation.handler; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.zy.acs.common.utils.News; |
| | | import com.zy.acs.common.utils.RedisSupport; |
| | | import com.zy.acs.conveyor.core.constant.RedisConveyorConstant; |
| | |
| | | } |
| | | // 判断是否满足条件 |
| | | if (staProtocol.isLoading()) { |
| | | //News.error("{}:站点:{},有物", config.getMark(), staProtocol.getSiteId()); |
| | | continue; |
| | | } |
| | | if (staProtocol.getWorkNo() > 0 && staProtocol.isAutoing()) { |
| | | if (!staProtocol.isAutoing()) { |
| | | News.error("{}:站点:{},非自动", config.getMark(), staProtocol.getSiteId()); |
| | | continue; |
| | | } |
| | | if (staProtocol.getWorkNo() > 0) { |
| | | Job job = jobService.getJobByJobNo(staProtocol.getWorkNo()); |
| | | if (job != null && job.getJobSts() == ConveyorStateType.SENDTASK.getStatus()) { |
| | | if (job == null) { |
| | | News.error("{}:站点:{},找不到任务", config.getMark(), staProtocol.getSiteId()); |
| | | continue; |
| | | } |
| | | if (job.getJobSts() != ConveyorStateType.SENDTASK.getStatus()) { |
| | | if (job.getJobSts() == ConveyorStateType.CLEARSIGNAL.getStatus()){ |
| | | continue; |
| | | } |
| | | News.error("{}:站点:{},任务状态不对,{}", config.getMark(), staProtocol.getSiteId(), JSON.toJSON(job)); |
| | | continue; |
| | | } |
| | | //String s = ctuMainService.checkStationStatus(takeSta.getStaNo()); |
| | | staProtocol.setWorkNo(0); |
| | | staProtocol.setStaNo(0); |
| | | redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol); |
| | | |
| | | job.setJobSts(ConveyorStateType.CLEARSIGNAL.getStatus()); |
| | | jobService.updateById(job); |
| | | //log.info("" + config.getMark() + "站点清空:{},{}", takeSta.getStaNo(), staProtocol.getWorkNo()); |
| | | if (!jobService.updateById(job)){ |
| | | log.info("" + config.getMark() + "站点清空失败:{},{}", takeSta.getStaNo(), staProtocol.getWorkNo()); |
| | | }else { |
| | | News.info("" + config.getMark() + "站点清空:{},{}", takeSta.getStaNo(), staProtocol.getWorkNo()); |
| | | } |
| | | } |
| | |
| | | package com.zy.acs.conveyor.core.operation.handler; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.zy.acs.common.utils.News; |
| | | import com.zy.acs.common.utils.RedisSupport; |
| | | import com.zy.acs.conveyor.core.constant.RedisConveyorConstant; |
| | | import com.zy.acs.conveyor.core.enums.ConveyorStateType; |
| | | import com.zy.acs.conveyor.core.model.SafeSignal; |
| | | import com.zy.acs.conveyor.core.model.StaProtocol; |
| | | import com.zy.acs.conveyor.core.operation.OperationHandler; |
| | | import com.zy.acs.conveyor.core.properties.CtuOperationConfig; |
| | |
| | | // 根据输送线plc遍历 |
| | | for (DevpSlave devp : slaveProperties.getDevp()) { |
| | | // 遍历出库口 |
| | | for (DevpSlave.Sta releaseSta : devp.getReleaseSta()) { |
| | | for (DevpSlave.Sta putSta : devp.getPutSta()) { |
| | | // 获取入库站信息 |
| | | Map<Integer, StaProtocol> stationMap = stationService.getStationMap(devp.getId()); |
| | | StaProtocol staProtocol = stationMap.get(releaseSta.getStaNo()); |
| | | StaProtocol staProtocol = stationMap.get(putSta.getStaNo()); |
| | | if (staProtocol == null) { |
| | | continue; |
| | | } else { |
| | | staProtocol = staProtocol.clone(); |
| | | } |
| | | // 判断是否满足条件 |
| | | if (!staProtocol.isLoading()) { |
| | | if (staProtocol.getWorkNo() > 0) { |
| | | News.error("输送线上有任务号无货,需要人工处理:{}", staProtocol.getSiteId()); |
| | | //log.error("输送线上有任务号无货,需要人工处理:{}", staProtocol.getSiteId()); |
| | | } |
| | | if (!staProtocol.isAutoing()) { |
| | | News.error("{},输送线未自动,需要开启:{}", config.getMark(), staProtocol.getSiteId()); |
| | | continue; |
| | | } |
| | | |
| | | if (staProtocol.isAutoing() && staProtocol.getWorkNo() == 0) { |
| | | if (staProtocol.isInEnable()) { |
| | | News.error("没有可入信号:{}", staProtocol.getSiteId()); |
| | | //log.error("没有可入信号:{}", staProtocol.getSiteId()); |
| | | if (staProtocol.getWorkNo() == 0 && staProtocol.isLoading()) { |
| | | String seqNum = ctuMainService.checkStationStatus(putSta.getStaNo()); |
| | | if (seqNum != null) { |
| | | staProtocol.setSafeSignal(new SafeSignal( devp.getPutSta().indexOf(putSta) ,true)); |
| | | redis.push(RedisConveyorConstant.CONVEYOR_SAFE_FLAG,staProtocol ); |
| | | |
| | | Job job = jobService.getJobByTaskNo(seqNum); |
| | | if (job != null) { |
| | | News.error("{}:站点:{},存在任务,{}", config.getMark(), staProtocol.getSiteId(), JSON.toJSON(job)); |
| | | continue; |
| | | } |
| | | String seqNum = ctuMainService.checkStationStatus(releaseSta.getStaNo()); |
| | | if (seqNum != null) { |
| | | if (jobService.getJobByTaskNo(seqNum) == null) { |
| | | int workNo = wrkLastnoService.nextWorkNo(WorkNoTypeType.WORK_NO_TYPE.type); |
| | | // 下发移动 且 下发plc命令 |
| | | staProtocol.setWorkNo(workNo); |
| | | staProtocol.setStaNo(releaseSta.getTargetSta()); |
| | | Job job = new Job(); |
| | | staProtocol.setStaNo(putSta.getTargetSta()); |
| | | job = new Job(); |
| | | job.setTaskNo(seqNum); |
| | | job.setJobNo(workNo); |
| | | job.setJobSts(ConveyorStateType.OUTBOUND.getStatus()); |
| | |
| | | throw new CoolException("插入输送线任务失败," + seqNum + " - " + workNo); |
| | | } |
| | | redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol); |
| | | log.info("输送线下发:{},{}", staProtocol.getWorkNo(), releaseSta.getTargetSta()); |
| | | News.info("{},输送线下发:{},{}", config.getMark(), staProtocol.getWorkNo(), putSta.getTargetSta()); |
| | | } else { |
| | | News.error("{},站点信息不符合入库条件!!!" + " 调用RCS检验未通过,站点:{}", config.getMark(), staProtocol.getSiteId()); |
| | | } |
| | | } else { |
| | | News.error("站点信息不符合入库条件!!!" + " 调用RCS检验未通过,站点:{}", staProtocol.getSiteId()); |
| | | //log.info("站点信息不符合入库条件!!!" + " 调用RCS检验未通过,站点:{}", staProtocol.getSiteId()); |
| | | } |
| | | News.error("{},站点:{},异常状态,请补充", config.getMark(), staProtocol.getSiteId()); |
| | | } |
| | | } |
| | | } |
| | |
| | | package com.zy.acs.conveyor.core.operation.handler; |
| | | |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.zy.acs.common.utils.News; |
| | | import com.zy.acs.common.utils.RedisSupport; |
| | | import com.zy.acs.conveyor.controller.vo.OpenBusSubmitParam; |
| | |
| | | staProtocol = staProtocol.clone(); |
| | | } |
| | | // 判断是否满足条件 |
| | | if (!staProtocol.isLoading()) { |
| | | if (staProtocol.getWorkNo() > 0) { |
| | | News.error("输送线上有货无任务号,需要人工处理:{}", staProtocol.getSiteId()); |
| | | //log.error("输送线上有任务号无货,需要人工处理:{}", staProtocol.getSiteId()); |
| | | } |
| | | if (staProtocol.getWorkNo() == 0 && staProtocol.isLoading()) { |
| | | News.error("{},输送线上有货无任务号,需要人工处理站点:{}", config.getMark(), staProtocol.getSiteId()); |
| | | continue; |
| | | } |
| | | if (staProtocol.getWorkNo() == 0) { |
| | | News.error("输送线上有货无任务号,需要人工处理:{}", staProtocol.getSiteId()); |
| | | //log.error("输送线上有货无任务号,需要人工处理:{}", staProtocol.getSiteId()); |
| | | if (staProtocol.getWorkNo() > 0 && !staProtocol.isLoading()) { |
| | | News.error("{},输送线上无货有任务号,需要人工处理站点:{}", config.getMark(), staProtocol.getSiteId()); |
| | | continue; |
| | | } |
| | | if (staProtocol.isAutoing()) { |
| | | Job job = jobService.getJobByJobNoAndJobSts(staProtocol.getWorkNo(), ConveyorStateType.INBOUND.getStatus()); |
| | | if (job != null) { |
| | | if (ctuMainService.sendTask(process(job))) { |
| | | job.setJobSts(ConveyorStateType.SENDTASK.getStatus()); |
| | | job.setRcsTime(new Date()); |
| | | jobService.updateById(job); |
| | | log.info("任务发送给RCS成功,WMS任务号:{},输送线工作号:{}", job.getTaskNo(), job.getJobNo()); |
| | | if (!staProtocol.isAutoing()) { |
| | | News.error("{}:站点:{},非自动", config.getMark(), staProtocol.getSiteId()); |
| | | continue; |
| | | } |
| | | if (staProtocol.isInEnable()) { |
| | | News.error("{},站点:{},没有可入信号", config.getMark(), staProtocol.getSiteId()); |
| | | continue; |
| | | } |
| | | Job jobByJobNo = jobService.getJobByJobNo(staProtocol.getWorkNo()); |
| | | if (jobByJobNo == null) { |
| | | News.error("{}:站点:{},找不到任务", config.getMark(), staProtocol.getSiteId()); |
| | | continue; |
| | | } |
| | | if (jobByJobNo.getJobSts() != ConveyorStateType.INBOUND.getStatus()) { |
| | | if (jobByJobNo.getJobSts() == ConveyorStateType.SENDTASK.getStatus()){ |
| | | continue; |
| | | } |
| | | News.error("{}:站点:{},任务状态不对,{}", config.getMark(), staProtocol.getSiteId(), JSON.toJSON(jobByJobNo)); |
| | | continue; |
| | | } |
| | | |
| | | if (ctuMainService.sendTask(process(jobByJobNo))) { |
| | | jobByJobNo.setJobSts(ConveyorStateType.SENDTASK.getStatus()); |
| | | jobByJobNo.setRcsTime(new Date()); |
| | | jobService.updateById(jobByJobNo); |
| | | News.error("{},任务发送给RCS成功,WMS任务号:{},输送线工作号:{}", config.getMark(), jobByJobNo.getTaskNo(), jobByJobNo.getJobNo()); |
| | | } else { |
| | | log.info("任务发送给RCS失败,WMS任务号:{},输送线工作号:{}", job.getTaskNo(), job.getJobNo()); |
| | | News.error("{},任务发送给RCS失败,WMS任务号:{},输送线工作号:{}", config.getMark(), jobByJobNo.getTaskNo(), jobByJobNo.getJobNo()); |
| | | } |
| | | } |
| | | } else { |
| | | log.error("输送线未自动,需要开启:{}", staProtocol.getSiteId()); |
| | | } |
| | | |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| New file |
| | |
| | | package com.zy.acs.conveyor.core.operation.handler; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.zy.acs.common.utils.News; |
| | | import com.zy.acs.common.utils.RedisSupport; |
| | | import com.zy.acs.conveyor.core.constant.RedisConveyorConstant; |
| | | import com.zy.acs.conveyor.core.enums.ConveyorStateType; |
| | | import com.zy.acs.conveyor.core.model.StaProtocol; |
| | | import com.zy.acs.conveyor.core.operation.OperationHandler; |
| | | import com.zy.acs.conveyor.core.properties.CtuOperationConfig; |
| | | import com.zy.acs.conveyor.core.properties.DevpSlave; |
| | | import com.zy.acs.conveyor.core.properties.SlaveProperties; |
| | | import com.zy.acs.conveyor.core.service.StationService; |
| | | import com.zy.acs.conveyor.entity.Job; |
| | | import com.zy.acs.conveyor.service.JobService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.transaction.interceptor.TransactionAspectSupport; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 模拟用户按按钮 |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class StartUpOperationHandler implements OperationHandler { |
| | | |
| | | @Autowired |
| | | private SlaveProperties slaveProperties; |
| | | |
| | | |
| | | @Autowired |
| | | private JobService jobService; |
| | | |
| | | |
| | | @Autowired |
| | | private StationService stationService; |
| | | |
| | | private final RedisSupport redis = RedisSupport.defaultRedisSupport; |
| | | |
| | | |
| | | @Override |
| | | public ConveyorStateType getType() { |
| | | return ConveyorStateType.STARTUP; |
| | | } |
| | | |
| | | @Override |
| | | public synchronized void execute(CtuOperationConfig config) { |
| | | |
| | | try { |
| | | // 根据输送线plc遍历 |
| | | for (DevpSlave devp : slaveProperties.getDevp()) { |
| | | // 遍历入库口 |
| | | for (DevpSlave.Sta inSta : devp.getInSta()) { |
| | | // 根据输送线plc遍历 |
| | | Map<Integer, StaProtocol> stationMap = stationService.getStationMap(devp.getId()); |
| | | StaProtocol staProtocol = stationMap.get(inSta.getSourceStaNo()); |
| | | if (staProtocol == null) { |
| | | continue; |
| | | } else { |
| | | staProtocol = staProtocol.clone(); |
| | | } |
| | | // 判断是否满足条件 |
| | | if (!staProtocol.isStartup() || !staProtocol.isAutoing() || !staProtocol.isLoading()) { |
| | | if (!staProtocol.isStartup()) { |
| | | News.error("{}:站点:{},未启动入库", config.getMark(), staProtocol.getSiteId()); |
| | | continue; |
| | | } |
| | | if (!staProtocol.isAutoing()) { |
| | | News.error("{}:站点:{},非自动", config.getMark(), staProtocol.getSiteId()); |
| | | continue; |
| | | } |
| | | if (!staProtocol.isLoading()) { |
| | | News.error("{}:站点:{},无物", config.getMark(), staProtocol.getSiteId()); |
| | | continue; |
| | | } |
| | | |
| | | } |
| | | Job jobByJobNo = jobService.getJobByJobNo(staProtocol.getWorkNo()); |
| | | if (jobByJobNo == null) { |
| | | News.error("{}:站点:{},找不到任务", config.getMark(), staProtocol.getSiteId()); |
| | | continue; |
| | | } |
| | | if (jobByJobNo.getJobSts() != ConveyorStateType.OUTBOUND.getStatus()) { |
| | | if (jobByJobNo.getJobSts() == ConveyorStateType.STARTUP.getStatus()){ |
| | | continue; |
| | | } |
| | | News.error("{}:站点:{},任务状态不对,{}", config.getMark(), staProtocol.getSiteId(), JSON.toJSON(jobByJobNo)); |
| | | continue; |
| | | } |
| | | staProtocol.setStaNo(inSta.getStaNo()); |
| | | redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol); |
| | | |
| | | jobByJobNo.setJobSts(ConveyorStateType.STARTUP.getStatus()); |
| | | if (!jobService.updateById(jobByJobNo)) { |
| | | News.info("{},启动入库:{},{}", config.getMark(), staProtocol.getWorkNo(), staProtocol.getStaNo()); |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); |
| | | } |
| | | } |
| | | } |
| | |
| | | @Data |
| | | public class CtuOperationConfig { |
| | | private ConveyorStateType type; |
| | | private int mark; |
| | | private String mark; |
| | | private int maxRetries = 3; |
| | | private long retryDelay = 500; |
| | | private Map<String, Object> params = new HashMap<>(); |
| | |
| | | |
| | | private Boolean staNosError; |
| | | |
| | | private List<Sta> releaseSta = new ArrayList<>(); |
| | | private List<Sta> putSta = new ArrayList<>(); |
| | | |
| | | private List<Sta> takeSta = new ArrayList<>(); |
| | | |
| | |
| | | @Data |
| | | public static class Sta { |
| | | |
| | | private Integer sourceStaNo; |
| | | |
| | | private Integer staNo; |
| | | |
| | | |
| | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.zy.acs.common.utils.News; |
| | | import com.zy.acs.conveyor.core.constant.PlcConstant; |
| | | import com.zy.acs.conveyor.core.constant.SafeSignalField; |
| | | import com.zy.acs.conveyor.core.constant.TaskField; |
| | | import com.zy.acs.conveyor.core.model.SafeSignal; |
| | | import com.zy.acs.conveyor.core.model.StaProtocol; |
| | | import com.zy.acs.conveyor.core.properties.DevpSlave; |
| | | import com.zy.acs.conveyor.core.properties.OutputQueue; |
| | |
| | | public void read(StaProtocol staProtocol, SiemensS7Net siemensS7Net) { |
| | | |
| | | } |
| | | public void writeSafe(StaProtocol staProtocol) throws InterruptedException { |
| | | if (staProtocol == null) { |
| | | log.warn("写入数据为空,跳过 [id:{}]", JSON.toJSONString(staProtocol)); |
| | | return; |
| | | } |
| | | |
| | | SiemensS7Net siemensS7Net = devpS7Service.get(staProtocol.getPlcId()); |
| | | if (siemensS7Net == null) { |
| | | log.error("PLC未连接,无法写入 [id:{}]", JSON.toJSONString(staProtocol)); |
| | | return; |
| | | } |
| | | |
| | | List<DevpSlave> devp = slaveProperties.getDevp(); |
| | | DevpSlave devpSlave = devp.stream().filter(slave -> slave.getId().equals(staProtocol.getPlcId())).findFirst().orElse(null); |
| | | if (devpSlave == null) { |
| | | log.error("PLC未配置,无法写入 [id:{}]", JSON.toJSONString(staProtocol)); |
| | | return; |
| | | } |
| | | int index = devpSlave.getStaNos().indexOf(staProtocol.getSiteId()); |
| | | if (index < 0) { |
| | | log.error("站点编号不存在于配置中 [id:{}] [siteId:{}]", staProtocol.getPlcId(), staProtocol.getSiteId()); |
| | | return; |
| | | } |
| | | SafeSignal safeSignal = staProtocol.getSafeSignal(); |
| | | |
| | | int baseOffset = SafeSignalField.SAFE_SIGNAL_FROM_CONVEYOR.getOffset() + safeSignal.getIndex() * SafeSignalField.SAFE_SIGNAL_FROM_CONVEYOR.getByteLength(); |
| | | String workNoAddr = TaskField.TASK_NUMBER.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION |
| | | + (baseOffset + TaskField.TASK_NUMBER.getOffset()); |
| | | String destStaAddr = TaskField.DEST_STATION.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION |
| | | + (baseOffset + TaskField.DEST_STATION.getOffset()); |
| | | |
| | | // 任务下发重试机制 |
| | | int writeCount = 0; |
| | | boolean success = false; |
| | | |
| | | while (writeCount < WRITE_RETRY_MAX) { |
| | | OperateResult writeResult = siemensS7Net.Write(workNoAddr, staProtocol.getWorkNo()); |
| | | Thread.sleep(WRITE_RETRY_INTERVAL_MS); |
| | | |
| | | OperateResult writeResult1 = siemensS7Net.Write(destStaAddr, staProtocol.getStaNo().shortValue()); |
| | | |
| | | if (writeResult.IsSuccess && writeResult1.IsSuccess) { |
| | | log.info("写入输送线命令成功 [id:{}] [siteId:{}] [workNo:{}] [destSta:{}] [retry:{}]", |
| | | staProtocol.getPlcId(), staProtocol.getSiteId(), staProtocol.getWorkNo(), |
| | | staProtocol.getStaNo(), writeCount); |
| | | OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线命令成功。输送线plc编号={1},站点数据={2}", |
| | | staProtocol.getPlcId(), JSON.toJSON(staProtocol))); |
| | | success = true; |
| | | break; |
| | | } |
| | | |
| | | writeCount++; |
| | | log.error("写入输送线命令失败 [id:{}] [siteId:{}] [retry:{}] [workErr:{}] [destErr:{}]", |
| | | staProtocol.getPlcId(), staProtocol.getSiteId(), writeCount, |
| | | writeResult.Message, writeResult1.Message); |
| | | |
| | | if (writeCount < WRITE_RETRY_MAX) { |
| | | Thread.sleep(WRITE_RETRY_INTERVAL_MS); |
| | | } |
| | | } |
| | | |
| | | if (!success) { |
| | | String errorMsg = MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", |
| | | staProtocol.getPlcId(), JSON.toJSON(staProtocol)); |
| | | OutputQueue.DEVP.offer(errorMsg); |
| | | News.error("SiemensDevp - 4 - 写入输送线站点数据失败。输送线plc编号={},站点数据={}", |
| | | staProtocol.getPlcId(), JSON.toJSON(staProtocol)); |
| | | log.error(errorMsg); |
| | | } |
| | | |
| | | } |
| | | |
| | | public void write(StaProtocol staProtocol) throws InterruptedException { |
| | | if (staProtocol == null) { |
| | |
| | | import com.zy.acs.common.utils.News; |
| | | import com.zy.acs.conveyor.core.constant.DeviceField; |
| | | import com.zy.acs.conveyor.core.constant.PlcAlarmDefinition; |
| | | import com.zy.acs.conveyor.core.constant.SafeSignalField; |
| | | import com.zy.acs.conveyor.core.constant.StationStatusField; |
| | | import com.zy.acs.conveyor.core.model.StaProtocol; |
| | | import com.zy.acs.conveyor.core.properties.DevpSlave; |
| | |
| | | // 读取PLC故障 |
| | | readPlcAlarms(staNos, staNoSize); |
| | | |
| | | // 读取安全交互信号 |
| | | readSaleSingle(slave.getPutSta(), slave.getTakeSta()); |
| | | |
| | | |
| | | // 定期更新数据库(降低频率) |
| | | updateDatabaseIfNeeded(); |
| | | } |
| | |
| | | staProtocol.setStaNo((int) siemensS7Net.getByteTransform().TransInt16( |
| | | content, offset + StationStatusField.FINAL_TARGET.getOffset())); |
| | | |
| | | boolean[] status = siemensS7Net.getByteTransform().TransBool( |
| | | boolean[] status0 = siemensS7Net.getByteTransform().TransBool( |
| | | content, offset + StationStatusField.STATUS_WORD.getOffset(), |
| | | StationStatusField.STATUS_WORD.getByteLength()); |
| | | |
| | | boolean[] status = siemensS7Net.getByteTransform().TransBool( |
| | | content, offset + StationStatusField.STATUS_WORD.getOffset(), |
| | | 1); |
| | | |
| | | staProtocol.setAutoing(status[0]); |
| | | staProtocol.setLoading(status[1]); |
| | |
| | | staProtocol.setFullPlt(status[5]); |
| | | staProtocol.setHigh(status[6]); |
| | | staProtocol.setLow(status[7]); |
| | | |
| | | boolean[] status2 = siemensS7Net.getByteTransform().TransBool( |
| | | content, offset + StationStatusField.STATUS_WORD.getOffset() + 1, |
| | | 1); |
| | | staProtocol.setMid(status2[0]); |
| | | staProtocol.setStartup(status2[1]); |
| | | staProtocol.setSegApply(status2[2]); |
| | | staProtocol.setApplyErr(status2[3]); |
| | | |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * 读取安全交互信号 |
| | | */ |
| | | private void readSaleSingle(List<DevpSlave.Sta> putSta, List<DevpSlave.Sta> takeSta) { |
| | | int staNoSize = putSta.size(); |
| | | OperateResultExOne<byte[]> result = siemensS7Net.Read( |
| | | SafeSignalField.SAFE_SIGNAL_FROM_CONVEYOR.buildAddress(), |
| | | (short) (staNoSize * SafeSignalField.SAFE_SIGNAL_FROM_CONVEYOR.getByteLength())); |
| | | |
| | | if (!result.IsSuccess) { |
| | | log.warn("读取PLC安全交互信息异常 [id:{}]", slave.getId()); |
| | | return; |
| | | } |
| | | |
| | | byte[] content = result.Content; |
| | | for (int i = 0; i < staNoSize; i++) { |
| | | Integer put = putSta.get(i).getStaNo(); |
| | | Integer take = takeSta.get(i).getStaNo(); |
| | | StaProtocol staProtocolPut = station.get(put); |
| | | StaProtocol staProtocolTake = station.get(take); |
| | | if (staProtocolPut == null || staProtocolTake == null) { |
| | | log.warn("站点不存在 [id:{}] [staNo:{},{}]", slave.getId(), put, take); |
| | | continue; |
| | | } |
| | | |
| | | boolean[] status = siemensS7Net.getByteTransform().TransBool( |
| | | content, i * SafeSignalField.SAFE_SIGNAL_FROM_CONVEYOR.getByteLength(), 1); |
| | | |
| | | boolean[] status2 = siemensS7Net.getByteTransform().TransBool( |
| | | content, i * SafeSignalField.SAFE_SIGNAL_FROM_CONVEYOR.getByteLength() + 2, 1); |
| | | |
| | | staProtocolPut.setHeartbeat(status[0]); |
| | | staProtocolPut.setAllowTake(status[1]); |
| | | staProtocolPut.setAllowPut(status[2]); |
| | | staProtocolPut.setInComplete(status[3]); |
| | | staProtocolPut.setOutComplete(status[4]); |
| | | |
| | | staProtocolTake.setHeartbeat(status2[0]); |
| | | staProtocolTake.setAllowTake(status2[1]); |
| | | staProtocolTake.setAllowPut(status2[2]); |
| | | staProtocolTake.setInComplete(status2[3]); |
| | | staProtocolTake.setOutComplete(status2[4]); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 按需更新数据库(降低更新频率) |
| | | */ |
| | | private void updateDatabaseIfNeeded() { |
| | |
| | | package com.zy.acs.conveyor.scheduler; |
| | | |
| | | import com.zy.acs.conveyor.core.enums.ConveyorStateType; |
| | | import com.zy.acs.conveyor.core.properties.CtuOperationConfig; |
| | | import com.zy.acs.conveyor.core.properties.CtuServiceProperties; |
| | | import com.zy.acs.conveyor.entity.Job; |
| | | import com.zy.acs.conveyor.mapper.JobMapper; |
| | |
| | | for (Job job : jobs) { |
| | | jobService.saveJobLog(job); |
| | | } |
| | | Boolean flag = true; |
| | | List<CtuOperationConfig> operations = properties.getOperations(); |
| | | for (CtuOperationConfig config : operations) { |
| | | if (config.getType().equals(ConveyorStateType.FAKEUSER)) { |
| | | flag = false; |
| | | } |
| | | } |
| | | if (flag) { |
| | | jobs = jobMapper.listJobToLog(ConveyorStateType.OUTBOUND.getStatus(), 1); |
| | | for (Job job : jobs) { |
| | | jobService.saveJobLog(job); |
| | | } |
| | | } else { |
| | | jobs = jobMapper.listJobToLog(ConveyorStateType.FAKEUSER.getStatus(), 1); |
| | | for (Job job : jobs) { |
| | | jobService.saveJobLog(job); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | interval: 1000 |
| | | operations: |
| | | - type: OUTBOUND |
| | | mark: 10 |
| | | mark: 出库流程 |
| | | max-retries: 3 |
| | | retry-delay: 800 |
| | | # - type: FAKEUSER |
| | | # mark: 20 |
| | | # max-retries: 2 |
| | | # retry-delay: 800 |
| | | - type: STARTUP |
| | | mark: 启动入库流程 |
| | | max-retries: 2 |
| | | retry-delay: 800 |
| | | - type: APPLYLOC |
| | | mark: 30 |
| | | mark: 申请入库流程 |
| | | max-retries: 2 |
| | | retry-delay: 2000 |
| | | # - type: INBOUND |
| | | # mark: 40 |
| | | # max-retries: 3 |
| | | # retry-delay: 500 |
| | | - type: CLEARSIGNAL |
| | | mark: 50 |
| | | mark: 清理信号流程 |
| | | max-retries: 2 |
| | | retry-delay: 800 |
| | | - type: SENDTASK |
| | | mark: 60 |
| | | mark: 发送任务RCS流程 |
| | | max-retries: 2 |
| | | retry-delay: 800 |
| | | |
| | |
| | | - 1011 |
| | | - 1012 |
| | | - 1013 |
| | | # 站点异常模块是否开启 |
| | | staNosError: true |
| | | # 扫码模块是否开启 |
| | | barcode: true |
| | | # 称重模块是否开启 |
| | | weight: true |
| | | # 取站点交互信号 |
| | | # ctu放货站点 |
| | | releaseSta[0]: |
| | | putSta[0]: |
| | | # 本站点 |
| | | staNo: 1001 |
| | | # 目标站点 |
| | | targetSta: 1007 |
| | | # ctu入库站点 |
| | | inSta[0]: |
| | | # 源站点 |
| | | sourceStaNo: 1007 |
| | | # 本站点 |
| | | staNo: 1010 |
| | | # 目标站点 |