| | |
| | | |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.github.xingshuangs.iot.protocol.s7.serializer.S7Serializer; |
| | | import com.kangaroohy.milo.model.ReadWriteEntity; |
| | | import com.kangaroohy.milo.service.MiloService; |
| | | import com.mes.common.config.Const; |
| | | import com.mes.engineering.entity.Engineering; |
| | | import com.mes.engineering.mapper.EngineeringMapper; |
| | | import com.mes.milo.model.ReadWriteEntity; |
| | | import com.mes.milo.service.MiloService; |
| | | import com.mes.opctask.entity.LoadGlassDeviceTask; |
| | | import com.mes.opctask.service.LoadGlassDeviceTaskService; |
| | | import com.mes.rawglassdetails.entity.RawGlassStorageDetails; |
| | | import com.mes.rawglassdetails.service.RawGlassStorageDetailsService; |
| | | import com.mes.rawglassstation.entity.RawGlassStorageStation; |
| | | import com.mes.rawglassstation.service.RawGlassStorageStationService; |
| | | import com.mes.rawglasstask.entity.RawGlassStorageTask; |
| | | import com.mes.rawglasstask.service.RawGlassStorageTaskService; |
| | | import com.mes.s7.entity.S7Data; |
| | | import com.mes.uppattenusage.entity.UpPattenUsage; |
| | | import com.mes.uppattenusage.entity.vo.UpPattenUsageVO; |
| | | import com.mes.uppattenusage.mapper.UpPattenUsageMapper; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.Arrays; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | |
| | | public class RawGlassTask { |
| | | |
| | | @Autowired |
| | | private RawGlassStorageStationService rawGlassStorageStationService; |
| | | @Autowired |
| | | private RawGlassStorageDetailsService rawGlassStorageDetailsService; |
| | | |
| | | @Autowired |
| | | private RawGlassStorageTaskService rawGlassStorageTaskService; |
| | | @Autowired |
| | | private RawGlassStorageStationService rawGlassStorageStationService; |
| | | |
| | | @Resource |
| | | private EngineeringMapper engineeringMapper; |
| | | @Resource |
| | | private UpPattenUsageMapper upPattenUsageMapper; |
| | | |
| | | @Autowired |
| | | @Resource |
| | | private LoadGlassDeviceTaskService loadGlassDeviceTaskService; |
| | | |
| | | @Autowired(required = false) |
| | | private MiloService miloService; |
| | | |
| | | private static final List<String> liftingStation = Arrays.asList("1", "2"); |
| | | private static final List<String> loadGlassStation = Arrays.asList("3", "4", "5", "6"); |
| | | @Autowired(required = false) |
| | | S7Serializer s7Serializer; |
| | | |
| | | |
| | | private static final String LOAD_GLASS_DEVICE_ONE_TASK = "load_glass_device_one_task"; |
| | | |
| | | private static final String LOAD_GLASS_DEVICE_TWO_TASK = "load_glass_device_two_task"; |
| | | |
| | | private static final List<Integer> LOAD_STATION_01 = Collections.singletonList(101); |
| | | // private static final List<Integer> LOAD_STATION_02 = Arrays.asList(103, 104); |
| | | // private static final List<Integer> LOAD_STATION_ALL = Arrays.asList(101, 102, 103, 104); |
| | | private static final Integer LEFTING_01 = 99; |
| | | // private static final Integer LEFTING_02 = 99; |
| | | private static final Integer LOAD_GLASS_ONE_DEVICE = 5; |
| | | private static final Integer LOAD_GLASS_TWO_DEVICE = 6; |
| | | |
| | | @Scheduled(fixedDelay = 1000) |
| | | public void rawStorageTask() throws Exception { |
| | | S7Data S7DataWL1 = s7Serializer.read(S7Data.class); |
| | | // S7Data S7DataWL1 = new S7Data(); |
| | | // S7DataWL1.setRequest((short) 1); |
| | | // S7DataWL1.setConfirmation((short) 0); |
| | | // S7DataWL1.setReportWord((short) 0); |
| | | // S7DataWL1.setTaskWord((short) 0); |
| | | // String requestWord = S7DataWL1.getRequest().toString(); |
| | | // String confireWord = S7DataWL1.getConfirmation().toString(); |
| | | // String reportWord = S7DataWL1.getReportWord().toString(); |
| | | // String taskWord = S7DataWL1.getTaskWord().toString(); |
| | | |
| | | String requestWord = S7DataWL1.getRequest().toString(); |
| | | String confireWord = S7DataWL1.getConfirmation().toString(); |
| | | String reportWord = S7DataWL1.getReportWord().toString(); |
| | | String taskWord = S7DataWL1.getTaskWord().toString(); |
| | | String requestValue = requestWord; |
| | | // ReadWriteEntity requestWord = miloService.readFromOpcUa("CC.CC.request"); |
| | | // ReadWriteEntity confireWord = miloService.readFromOpcUa("CC.CC.confirmation"); |
| | | // ReadWriteEntity reportWord = miloService.readFromOpcUa("CC.CC.reportWord"); |
| | | // ReadWriteEntity taskWord = miloService.readFromOpcUa("CC.CC.taskWord"); |
| | | // String requestValue = requestWord.getValue() + ""; |
| | | if ("0".equals(requestValue)) { |
| | | if ("1".equals(confireWord) && "0".equals(reportWord)) { |
| | | // if ("1".equals(confireWord.getValue() + "") && "0".equals(reportWord.getValue() + "")) { |
| | | S7Data s7Data = new S7Data(); |
| | | s7Data.setConfirmation((short) 0); |
| | | s7Serializer.write(s7Data); |
| | | // List<ReadWriteEntity> list = new ArrayList<>(); |
| | | // list.add(generateReadWriteEntity("CC.CC.confirmation", 0)); |
| | | // miloService.writeToOpcWord(list); |
| | | } |
| | | if ("1".equals(taskWord)) { |
| | | // if ("1".equals(taskWord.getValue() + "")) { |
| | | S7Data s7Data = new S7Data(); |
| | | s7Data.setTaskWord((short) 0); |
| | | s7Data.setStartSlot((short) 0); |
| | | s7Data.setEndSlot((short) 0); |
| | | s7Serializer.write(s7Data); |
| | | // List<ReadWriteEntity> list = new ArrayList<>(); |
| | | // list.add(generateReadWriteEntity("CC.CC.taskWord", 0)); |
| | | // list.add(generateReadWriteEntity("CC.CC.startSlot", 0)); |
| | | // list.add(generateReadWriteEntity("CC.CC.endSlot", 0)); |
| | | // miloService.writeToOpcWord(list); |
| | | } |
| | | return; |
| | | } |
| | | if (!"1".equals(requestValue)) { |
| | | log.info("无请求"); |
| | | return; |
| | | } |
| | | //是否有正在执行的任务 |
| | | boolean flag = isHasRunningTask(); |
| | | if (flag) { |
| | | log.info("有未完成的任务,结束"); |
| | | return; |
| | | } |
| | | //todo:优先进上片机位 |
| | | flag = rawGlassDispatchTask(); |
| | | if (flag) { |
| | | log.info("执行调度任务,结束"); |
| | | return; |
| | | } |
| | | flag = inboundRequestTask(); |
| | | if (flag) { |
| | | log.info("执行吊装位请求任务"); |
| | | return; |
| | | } |
| | | flag = warehouseTask(); |
| | | if (flag) { |
| | | log.info("执行回库任务"); |
| | | return; |
| | | } |
| | | flag = outboundTask(); |
| | | if (flag) { |
| | | log.info("执行出库任务,结束"); |
| | | return; |
| | | } |
| | | log.info("无任务执行,结束"); |
| | | } |
| | | |
| | | @Scheduled(fixedDelay = 1000) |
| | | public void rawStorageInCar() throws Exception { |
| | | S7Data S7DataWL1 = s7Serializer.read(S7Data.class); |
| | | // S7Data S7DataWL1 = new S7Data(); |
| | | // S7DataWL1.setInCar((short) 1); |
| | | String value = S7DataWL1.getInCar().toString(); |
| | | // ReadWriteEntity entity = miloService.readFromOpcUa("CC.CC.inCar"); |
| | | // String value = entity.getValue() + ""; |
| | | if (!"1".equals(value)) { |
| | | log.info("大车上没有架子"); |
| | | return; |
| | | } |
| | | //查询任务 |
| | | RawGlassStorageDetails one = rawGlassStorageDetailsService.getOne(new LambdaQueryWrapper<RawGlassStorageDetails>() |
| | | .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING)); |
| | | if (one == null) { |
| | | log.info("没有正在执行的任务"); |
| | | return; |
| | | } |
| | | rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>().eq(RawGlassStorageDetails::getId, one.getId()) |
| | | .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_CAR)); |
| | | } |
| | | |
| | | @Scheduled(fixedDelay = 1000) |
| | | public void rawStorageFinish() throws Exception { |
| | | S7Data S7DataWL1 = s7Serializer.read(S7Data.class); |
| | | // S7Data S7DataWL1 = new S7Data(); |
| | | // S7DataWL1.setReportWord((short) 1); |
| | | String value = S7DataWL1.getReportWord().toString(); |
| | | // ReadWriteEntity entity = miloService.readFromOpcUa("CC.CC.reportWord"); |
| | | // String value = entity.getValue() + ""; |
| | | if ("0".equals(value)) { |
| | | log.info("当前任务未汇报,结束本次任务"); |
| | | return; |
| | | } |
| | | RawGlassStorageDetails details = rawGlassStorageDetailsService.getOne(new LambdaUpdateWrapper<RawGlassStorageDetails>() |
| | | .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_CAR)); |
| | | if (null == details) { |
| | | log.info("无执行中的任务"); |
| | | return; |
| | | } |
| | | RawGlassStorageTask task = rawGlassStorageTaskService.getOne(new LambdaQueryWrapper<RawGlassStorageTask>() |
| | | .in(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING, Const.RAW_GLASS_TASK_NEW)); |
| | | RawGlassStorageDetails targetDetails = rawGlassStorageDetailsService.generateDetails(details, task.getEndSlot()); |
| | | int deviceId = details.getDeviceId(); |
| | | Integer taskType = task.getTaskType(); |
| | | if ("1".equals(value)) { |
| | | log.info("将详情表的状态改为已出库"); |
| | | rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>() |
| | | .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_OUT) |
| | | .eq(RawGlassStorageDetails::getSlot, task.getStartSlot()).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_CAR)); |
| | | log.info("任务状态已更改为:已完成"); |
| | | rawGlassStorageTaskService.update(new LambdaUpdateWrapper<RawGlassStorageTask>() |
| | | .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING) |
| | | .set(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_SUCCESS)); |
| | | switch (taskType) { |
| | | case 1: |
| | | case 3: |
| | | log.info("1、入库,3、调度任务。{}", taskType); |
| | | if (targetDetails.getRemainQuantity() > 0) { |
| | | rawGlassStorageDetailsService.save(targetDetails); |
| | | } |
| | | break; |
| | | case 2: |
| | | case 4: |
| | | log.info("2、出片,4、吊装位请求。{}", taskType); |
| | | targetDetails = new RawGlassStorageDetails(); |
| | | targetDetails.setSlot(task.getEndSlot()); |
| | | targetDetails.setDeviceId(deviceId); |
| | | targetDetails.setShelf(task.getStartSlot()); |
| | | targetDetails.setState(Const.RAW_GLASS_STATE_IN); |
| | | rawGlassStorageDetailsService.save(targetDetails); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } else { |
| | | if (taskType.equals(Const.RAW_GLASS_TASK_TYPE_IN_REQUEST)) { |
| | | rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>() |
| | | .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_OUT) |
| | | .eq(RawGlassStorageDetails::getSlot, task.getStartSlot()) |
| | | .in(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING, Const.RAW_GLASS_STATE_CAR)); |
| | | } else { |
| | | rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>() |
| | | .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN) |
| | | .eq(RawGlassStorageDetails::getSlot, task.getStartSlot()) |
| | | .in(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING, Const.RAW_GLASS_STATE_CAR)); |
| | | } |
| | | rawGlassStorageTaskService.update(new LambdaUpdateWrapper<RawGlassStorageTask>() |
| | | .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING) |
| | | .set(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_FAILURE)); |
| | | |
| | | } |
| | | S7Data s7Data = new S7Data(); |
| | | s7Data.setConfirmation((short) 1); |
| | | s7Serializer.write(s7Data); |
| | | } |
| | | |
| | | private boolean isHasRunningTask() { |
| | | RawGlassStorageTask task = rawGlassStorageTaskService.getOne(new LambdaQueryWrapper<RawGlassStorageTask>() |
| | | .in(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING)); |
| | | return task == null ? Boolean.FALSE : Boolean.TRUE; |
| | | } |
| | | |
| | | /** |
| | | * 原片调度:1、查询工程原片表,按照顺序将原片放入上片1号位,后续原片放上片2号位,出现尺寸替换,判断原上片位是否有玻璃,有 先出后进,无 直接进片 |
| | | */ |
| | | public boolean rawGlassDispatchTask() throws Exception { |
| | | //查询当前系统正在执行的订单 |
| | | List<Engineering> engineeringList = engineeringMapper.selectList(new LambdaQueryWrapper<Engineering>() |
| | | .eq(Engineering::getState, Const.ENGINEERING_RUNNING).last("order by id")); |
| | | if (CollectionUtils.isEmpty(engineeringList)) { |
| | | log.info("没有正在执行的工程"); |
| | | return false; |
| | | } |
| | | for (Engineering engineering : engineeringList) { |
| | | boolean flag = rawGlassDispatchByEngineering(engineering.getStationCell(), engineering.getEngineerId()); |
| | | if (flag) { |
| | | return flag; |
| | | } |
| | | } |
| | | return Boolean.FALSE; |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 处理空架子吊装位请求任务:将仓库的空架子送到吊装位99,等待入库 |
| | | * |
| | | * @return |
| | | */ |
| | | public boolean inboundRequestTask() throws Exception { |
| | | // 步骤1:查询“未执行的空架子到吊装位请求任务”(类型IN_REQUEST,状态NEW) |
| | | RawGlassStorageTask inRequestTask = rawGlassStorageTaskService.getOne(new LambdaQueryWrapper<RawGlassStorageTask>() |
| | | .eq(RawGlassStorageTask::getTaskType, Const.RAW_GLASS_TASK_TYPE_IN_REQUEST) // 空架子入库请求类型 |
| | | .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW) |
| | | .last("limit 1")); // 每次处理一个任务,避免冲突 |
| | | |
| | | if (inRequestTask == null) { |
| | | log.info("无待执行的空架子吊装位请求任务"); |
| | | return Boolean.FALSE; |
| | | } |
| | | |
| | | // 步骤2:检查任务关联的空架子状态(需为“待入库”,且确实是空架子) |
| | | RawGlassStorageDetails emptyShelf = rawGlassStorageDetailsService.getOne(new LambdaQueryWrapper<RawGlassStorageDetails>() |
| | | .eq(RawGlassStorageDetails::getSlot, inRequestTask.getStartSlot()) // 起始位:仓库空架子位 |
| | | .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING)); // 待入库状态); |
| | | |
| | | if (emptyShelf == null) { |
| | | log.info("空架子到吊装位请求任务关联的架子异常(非空架子或状态错误),跳过执行"); |
| | | return Boolean.FALSE; |
| | | } |
| | | |
| | | // 步骤3:检查目标吊装位99是否空闲 |
| | | List<RawGlassStorageDetails> liftingShelfList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>() |
| | | .eq(RawGlassStorageDetails::getSlot, inRequestTask.getEndSlot()) // 目标位:吊装位99 |
| | | .in(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN_ALL)); |
| | | |
| | | if (CollectionUtil.isNotEmpty(liftingShelfList)) { |
| | | log.info("吊装位{}已有关联架子,无法执行空架子到吊装位请求", inRequestTask.getEndSlot()); |
| | | return Boolean.FALSE; |
| | | } |
| | | |
| | | // 步骤4:更新空架子状态为“执行中” |
| | | rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>() |
| | | .eq(RawGlassStorageDetails::getSlot, emptyShelf.getSlot()) |
| | | .eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN) |
| | | .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING)); |
| | | |
| | | // 步骤5:更新任务状态为“执行中”,避免重复执行 |
| | | rawGlassStorageTaskService.update(new LambdaUpdateWrapper<RawGlassStorageTask>() |
| | | .eq(RawGlassStorageTask::getId, inRequestTask.getId()) |
| | | .set(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING)); |
| | | |
| | | // 步骤6:发送PLC指令,驱动空架子从仓库→吊装位 |
| | | S7Data s7Data = new S7Data(); |
| | | s7Data.setTaskWord((short) 1); // 任务触发信号 |
| | | s7Data.setStartSlot((short) inRequestTask.getStartSlot().intValue()); // 起始位:仓库空架子位 |
| | | s7Data.setEndSlot((short) inRequestTask.getEndSlot().intValue()); // 目标位:吊装位99 |
| | | s7Serializer.write(s7Data); |
| | | |
| | | log.info("执行空架子到吊装位请求任务:从仓库{}到吊装位{}", inRequestTask.getStartSlot(), inRequestTask.getEndSlot()); |
| | | return Boolean.TRUE; |
| | | } |
| | | |
| | | /** |
| | | * 出库任务:1、点出库,立马生成出片任务 2、点出库修改工位详情内的状态为待出库,定时任务扫描生成出库任务 |
| | | */ |
| | | public boolean outboundTask() throws Exception { |
| | | // 步骤1:查询已生成的“未执行出库任务”(状态为NEW,类型为OUT) |
| | | RawGlassStorageTask outboundTask = rawGlassStorageTaskService.getOne(new LambdaQueryWrapper<RawGlassStorageTask>() |
| | | .eq(RawGlassStorageTask::getTaskType, Const.RAW_GLASS_TASK_TYPE_OUT) |
| | | .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW) |
| | | .last("limit 1")); // 每次处理一个任务 |
| | | |
| | | if (outboundTask == null) { |
| | | log.info("无待执行的出库任务"); |
| | | return Boolean.FALSE; |
| | | } |
| | | |
| | | // 步骤2:获取任务关联的架子详情,检查状态是否合法(待出库) |
| | | RawGlassStorageDetails details = rawGlassStorageDetailsService.getOne(new LambdaQueryWrapper<RawGlassStorageDetails>() |
| | | .eq(RawGlassStorageDetails::getSlot, outboundTask.getStartSlot()) // 任务起始位(仓库位) |
| | | .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_WAIT_OUT)); // 待出库状态 |
| | | if (details == null) { |
| | | log.info("出库任务关联的架子状态异常,跳过执行"); |
| | | return Boolean.FALSE; |
| | | } |
| | | |
| | | // 步骤3:检查吊装位99是否空闲(无架子) |
| | | List<RawGlassStorageDetails> emptyLeftingList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>() |
| | | .in(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN_ALL) |
| | | .in(RawGlassStorageDetails::getSlot, "select slot from raw_glass_storage_station where enable_state = 1 and device_id = 4")); |
| | | |
| | | if (CollectionUtil.isNotEmpty(emptyLeftingList)) { |
| | | log.info("吊装位99当前有架子,无法执行出库任务"); |
| | | return Boolean.FALSE; |
| | | } |
| | | |
| | | // 步骤4:更新架子状态为“执行中” |
| | | rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>() |
| | | .eq(RawGlassStorageDetails::getSlot, details.getSlot()) |
| | | .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_WAIT_OUT) |
| | | .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING)); |
| | | |
| | | // 步骤5:更新任务状态为“执行中”(避免重复执行) |
| | | rawGlassStorageTaskService.update(new LambdaUpdateWrapper<RawGlassStorageTask>() |
| | | .eq(RawGlassStorageTask::getId, outboundTask.getId()) |
| | | .set(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING)); |
| | | |
| | | |
| | | S7Data s7Data = new S7Data(); |
| | | s7Data.setTaskWord((short) 1); |
| | | s7Data.setStartSlot((short) outboundTask.getStartSlot().intValue()); // 仓库存储位(起始位) |
| | | s7Data.setEndSlot((short) outboundTask.getEndSlot().intValue()); // 吊装位99(目标位) |
| | | s7Serializer.write(s7Data); |
| | | |
| | | return Boolean.TRUE; |
| | | } |
| | | |
| | | /** |
| | | * 复位任务:1、点复位,立马生成复位任务 2、点出库修改工位详情内的状态为架子复位,定时任务扫描生成复位任务 |
| | | */ |
| | | public boolean shelfResetTask() throws Exception { |
| | | // 1. 查询“待复位”的架子(状态为RESET,且工位启用) |
| | | List<RawGlassStorageDetails> rawGlassList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>() |
| | | .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RESET) |
| | | .inSql(RawGlassStorageDetails::getSlot, "select slot from raw_glass_storage_station where enable_state = 1")); |
| | | if (CollectionUtil.isEmpty(rawGlassList)) { |
| | | log.info("系统没有需要复位的原片信息"); |
| | | return Boolean.FALSE; |
| | | } |
| | | |
| | | // 2. 取第一条待复位的架子(每次处理一个) |
| | | RawGlassStorageDetails details = rawGlassList.get(0); |
| | | Integer startSlot = details.getSlot(); // 复位起始位(当前架子所在位) |
| | | Integer targetSlot = details.getShelf(); // 复位目标位(初始仓库存储位) |
| | | |
| | | // 3. 生成复位任务(类型建议单独定义:如Const.RAW_GLASS_TASK_TYPE_RESET,避免与调度任务混淆) |
| | | rawGlassStorageDetailsService.generateTask( |
| | | startSlot, |
| | | targetSlot, |
| | | targetSlot, |
| | | details.getRemainQuantity(), |
| | | Const.RAW_GLASS_TASK_TYPE_DISPATCH |
| | | ); |
| | | |
| | | // 4. 更新架子状态为“执行中” |
| | | rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>() |
| | | .eq(RawGlassStorageDetails::getSlot, startSlot) |
| | | .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RESET) |
| | | .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING)); |
| | | |
| | | // 5. 补充PLC交互:发送复位指令 |
| | | S7Data s7Data = new S7Data(); |
| | | s7Data.setTaskWord((short) 1); // 任务触发信号 |
| | | s7Data.setStartSlot((short) startSlot.intValue()); // 起始位:当前架子位 |
| | | s7Data.setEndSlot((short) targetSlot.intValue()); // 目标位:初始仓库位 |
| | | s7Serializer.write(s7Data); |
| | | |
| | | log.info("执行架子复位任务:从{}到{}", startSlot, targetSlot); |
| | | return Boolean.TRUE; |
| | | } |
| | | |
| | | /** |
| | | * 入库任务:吊装位有玻璃,先去工位表查询空格子,生成入库任务从吊装位到目标格子 |
| | | * |
| | | * @throws Exception |
| | | */ |
| | | @Scheduled(fixedDelay = 1000) |
| | | public void warehouseTask() throws Exception { |
| | | ReadWriteEntity entity = miloService.readFromOpcUa("rawglass.device.request"); |
| | | String value = entity.getValueString(); |
| | | if (!"1".equals(value)) { |
| | | log.info("大车忙碌"); |
| | | return; |
| | | } |
| | | List<RawGlassStorageDetails> rawGlassList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>() |
| | | .eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN) |
| | | .inSql(RawGlassStorageDetails::getSlotId, "select slot from raw_glass_storage_station where enable_state = 1 and slot in (1,2)")); |
| | | if (CollectionUtil.isEmpty(rawGlassList)) { |
| | | log.info("吊装位被禁用或没有玻璃"); |
| | | return; |
| | | } |
| | | //查询工位信息是否有 |
| | | List<RawGlassStorageStation> stationList = rawGlassStorageStationService.list(new LambdaQueryWrapper<RawGlassStorageStation>().notInSql(RawGlassStorageStation::getSlot, "select slot_id from raw_glass_storage_details where state = '100'") |
| | | .eq(RawGlassStorageStation::getEnableState, Const.SLOT_ON)); |
| | | if (CollectionUtil.isEmpty(stationList)) { |
| | | log.info("没有空的工位"); |
| | | return; |
| | | } |
| | | //生成进笼任务 |
| | | generateTask(rawGlassList.get(0).getSlotId(), stationList.get(0).getSlot(), |
| | | rawGlassList.get(0).getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_IN); |
| | | //生成工位任务,将吊装位的玻璃状态改位进笼中 |
| | | } |
| | | public boolean warehouseTask() throws Exception { |
| | | // List<RawGlassStorageDetails> rawGlassList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>() |
| | | // .eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN) |
| | | // .gt(RawGlassStorageDetails::getRemainQuantity, 0) |
| | | // .inSql(RawGlassStorageDetails::getSlot, "select slot from raw_glass_storage_station where enable_state = 1 and device_id = 4") |
| | | // .inSql(RawGlassStorageDetails::getShelf, "select slot from raw_glass_storage_station where enable_state = 1 ")); |
| | | // if (CollectionUtil.isEmpty(rawGlassList)) { |
| | | // log.info("吊装位被禁用/架子所在工位被禁用/无原片信息"); |
| | | // return Boolean.FALSE; |
| | | // } |
| | | // 查询回库任务 |
| | | RawGlassStorageTask task = rawGlassStorageTaskService.getOne(new LambdaQueryWrapper<RawGlassStorageTask>() |
| | | .in(RawGlassStorageTask::getTaskType, Const.RAW_GLASS_TASK_TYPE_IN) |
| | | .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW) |
| | | .last("limit 1")); |
| | | |
| | | if (task == null) { |
| | | log.info("无待执行的回库任务"); |
| | | return false; |
| | | } |
| | | RawGlassStorageDetails details = rawGlassStorageDetailsService.getOne(new LambdaQueryWrapper<RawGlassStorageDetails>() |
| | | .eq(RawGlassStorageDetails::getSlot, task.getStartSlot()) // 任务起始位(吊装位) |
| | | .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING)); // 已标记为执行中 |
| | | if (details == null) { |
| | | log.info("任务关联的架子状态异常,跳过执行"); |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 出库任务:1、点出库,立马生成出片任务 2、点出库修改工位详情内的状态为待出库,定时任务扫描生成出库任务 |
| | | */ |
| | | @Scheduled(fixedDelay = 1000) |
| | | public void outboundTask() throws Exception { |
| | | ReadWriteEntity entity = miloService.readFromOpcUa("rawglass.device.request"); |
| | | String value = entity.getValueString(); |
| | | if (!"2".equals(value)) { |
| | | log.info("大车忙碌"); |
| | | return; |
| | | } |
| | | List<RawGlassStorageDetails> rawGlassList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>() |
| | | .eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_OUT_ING) |
| | | .inSql(RawGlassStorageDetails::getSlotId, "select slot from raw_glass_storage_station where enable_state = 1 and slot not in (1,2)")); |
| | | if (CollectionUtil.isEmpty(rawGlassList)) { |
| | | log.info("系统没有需要出库的原片信息"); |
| | | return; |
| | | } |
| | | List<Integer> emptyLeftingList = rawGlassStorageDetailsService.listBySlotState(liftingStation, Arrays.asList(Const.GLASS_STATE_IN)); |
| | | if (CollectionUtil.isEmpty(emptyLeftingList)) { |
| | | log.info("吊装位当前都有原片,结束出片任务"); |
| | | } |
| | | //生成出库任务 |
| | | generateTask(rawGlassList.get(0).getSlotId(), emptyLeftingList.get(0), |
| | | rawGlassList.get(0).getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_OUT); |
| | | rawGlassStorageTaskService.update(new LambdaUpdateWrapper<RawGlassStorageTask>() |
| | | .eq(RawGlassStorageTask::getId, task.getId()) |
| | | .set(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING)); |
| | | log.info("执行回库任务:从{}到{}", task.getStartSlot(), task.getEndSlot()); |
| | | // List<ReadWriteEntity> list = new ArrayList<>(); |
| | | // list.add(generateReadWriteEntity("CC.CC.taskWord", 1)); |
| | | // list.add(generateReadWriteEntity("CC.CC.taskSending", 1)); |
| | | // list.add(generateReadWriteEntity("CC.CC.startSlot", details.getSlot())); |
| | | // list.add(generateReadWriteEntity("CC.CC.endSlot", details.getShelf())); |
| | | // miloService.writeToOpcWord(list); |
| | | |
| | | S7Data s7Data = new S7Data(); |
| | | s7Data.setTaskWord((short) 1); |
| | | s7Data.setStartSlot((short) details.getSlot().intValue()); |
| | | s7Data.setEndSlot((short) details.getShelf().intValue()); |
| | | s7Serializer.write(s7Data); |
| | | return Boolean.TRUE; |
| | | } |
| | | |
| | | /** |
| | | * 原片调度:1、查询工程原片表,按照顺序将原片放入上片1号位,后续原片放上片2号位,出现尺寸替换,判断原上片位是否有玻璃,有 先出后进,无 直接进片 |
| | | * @param stationCell 设备信息 5 、 6 |
| | | * @param enginneerId 共亨号 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | @Scheduled(fixedDelay = 1000) |
| | | public void rawGlassDispatchTask() throws Exception { |
| | | ReadWriteEntity entity = miloService.readFromOpcUa("rawglass.device.request"); |
| | | String value = entity.getValueString(); |
| | | if (!"2".equals(value)) { |
| | | log.info("大车忙碌"); |
| | | return; |
| | | } |
| | | //查询当前系统正在执行的订单 |
| | | Engineering engineering = engineeringMapper.selectOne(new LambdaQueryWrapper<Engineering>().eq(Engineering::getState, Const.ENGINEERING_RUNNING).last("order by id limit 1")); |
| | | if (null == engineering) { |
| | | log.info("没有正在执行的工程"); |
| | | return; |
| | | } |
| | | private boolean rawGlassDispatchByEngineering(int stationCell, String enginneerId) throws Exception { |
| | | //当前尺寸需要上片的数量 |
| | | List<UpPattenUsageVO> pattenUsageList = upPattenUsageMapper.queryRawGlassByEngineeringId(engineering.getEngineerId()); |
| | | List<UpPattenUsageVO> pattenUsageList = upPattenUsageMapper.queryRawGlassByEngineeringId(enginneerId); |
| | | if (CollectionUtils.isEmpty(pattenUsageList)) { |
| | | log.info("正在执行的工程原片无可上片的原片信息"); |
| | | return Boolean.FALSE; |
| | | } |
| | | //获取当前需要上片的原片数据 |
| | | Map<String, List<UpPattenUsageVO>> upListMap = pattenUsageList.stream() |
| | | .collect(Collectors.groupingBy(UpPattenUsageVO::getGroupNumber)); |
| | | //todo:按照工程号按照工程下未完成的尺寸的顺序,当1号上片位架子上的当前尺寸玻璃少于3片且2号上片位无原片玻璃,则将去调度玻璃去2号上片位, |
| | | //todo:当一号上片位架子上的玻璃位空或者当前尺寸用完时时,将2号(有玻璃)上片位调度到1号上片位 |
| | | //1、查询4个上片的原片详情 |
| | | List<RawGlassStorageDetails> rawGlassDetailsList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>() |
| | | .eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN).in(RawGlassStorageDetails::getSlotId, loadGlassStation)); |
| | | if (CollectionUtils.isEmpty(rawGlassDetailsList)) { |
| | | //表示1上片位没有原片,直接找原片放入对应的上片位 |
| | | //结束调度任务 |
| | | } |
| | | Map<Integer, List<RawGlassStorageDetails>> listMap = rawGlassDetailsList.stream().collect(Collectors.groupingBy(RawGlassStorageDetails::getSlotId)); |
| | | RawGlassStorageDetails rawGlass03Details = listMap.get(3).get(0); |
| | | RawGlassStorageDetails rawGlass04Details = listMap.get(4).get(0); |
| | | // RawGlassStorageDetails rawGlass05Details = listMap.get(5).get(0); |
| | | // RawGlassStorageDetails rawGlass06Details = listMap.get(6).get(0); |
| | | //todo:上片1号位2种清空方式:方式一:原片用完 方式二:当前尺寸用完 |
| | | if (null == rawGlass03Details) { |
| | | if (null == rawGlass04Details) { |
| | | //表示1上片位没有原片,直接找原片放入对应的上片位 |
| | | //结束调度任务 |
| | | } else { |
| | | //将2号上片位的原片放入1号上片位 |
| | | //结束调度任务 |
| | | } |
| | | } else { |
| | | //原片剩余数量 |
| | | Integer quantity = rawGlass03Details.getRemainQuantity(); |
| | | List<UpPattenUsageVO> upPattenUsage01VOS = upListMap.get("1"); |
| | | if (null == rawGlass04Details) { |
| | | //todo:判断2号上片位需要的原片信息 |
| | | if (quantity < upPattenUsage01VOS.size()) { |
| | | //todo:继续上一号上片位当前的尺寸 |
| | | } else { |
| | | //todo:切换尺寸,上后续组的尺寸 |
| | | List<UpPattenUsageVO> upPattenUsage02VOS = upListMap.get("2"); |
| | | } |
| | | } |
| | | List<UpPattenUsageVO> usageVOS = upListMap.get("1"); |
| | | //获取当前上片位1号架子信息 |
| | | List<Integer> loadStation = LOAD_STATION_01; |
| | | List<RawGlassStorageStation> stations = rawGlassStorageStationService.list(new LambdaQueryWrapper<RawGlassStorageStation>() |
| | | .in(RawGlassStorageStation::getSlot, loadStation) |
| | | .eq(RawGlassStorageStation::getEnableState, Const.SLOT_ON) |
| | | .orderByAsc(RawGlassStorageStation::getSlot)); |
| | | if (CollectionUtils.isEmpty(stations)) { |
| | | log.info("101的上片位不可用"); |
| | | return Boolean.FALSE; |
| | | } |
| | | |
| | | List<RawGlassStorageDetails> loadStationList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>() |
| | | .inSql(RawGlassStorageDetails::getSlot, "select slot from raw_glass_storage_station where enable_state = 1") |
| | | .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN) |
| | | .eq(RawGlassStorageDetails::getDeviceId, stationCell)); |
| | | if (CollectionUtils.isEmpty(loadStationList)) { |
| | | RawGlassStorageDetails rawDetails = getRawGlassStorageDetailsBySize(usageVOS.get(0), usageVOS.size()); |
| | | if (rawDetails == null) { |
| | | log.info("仓库无匹配规格的原片,无法调度到101工位"); |
| | | return Boolean.FALSE; |
| | | } |
| | | // 生成调度任务:仓库原片位 → 101上片位 |
| | | rawGlassStorageDetailsService.generateTask( |
| | | rawDetails.getSlot(), |
| | | stations.get(0).getSlot(), |
| | | rawDetails.getShelf(), |
| | | rawDetails.getRemainQuantity(), |
| | | Const.RAW_GLASS_TASK_TYPE_DISPATCH); |
| | | |
| | | rawGlassStorageTaskService.update(new LambdaUpdateWrapper<RawGlassStorageTask>() |
| | | .eq(RawGlassStorageTask::getTaskType, Const.RAW_GLASS_TASK_TYPE_DISPATCH) |
| | | .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW) |
| | | .set(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING)); |
| | | |
| | | rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>() |
| | | .eq(RawGlassStorageDetails::getSlot, rawDetails.getSlot()) |
| | | .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN) |
| | | .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING)); |
| | | S7Data s7Data = new S7Data(); |
| | | s7Data.setTaskWord((short) 1); |
| | | s7Data.setStartSlot((short) rawDetails.getSlot().intValue()); // 起始位:仓库 |
| | | s7Data.setEndSlot((short) LOAD_STATION_01.get(0).intValue()); // 目标位:上片位101 |
| | | s7Serializer.write(s7Data); // 发送到PLC |
| | | |
| | | log.info("调度任务已发送PLC:从仓库{}到上片位{}", rawDetails.getSlot(), LOAD_STATION_01); |
| | | return Boolean.TRUE; |
| | | } |
| | | // 上片位101有玻璃 → 判断尺寸是否匹配 |
| | | RawGlassStorageDetails oneLoadStation = loadStationList.get(0); |
| | | if (oneLoadStation.getRemainQuantity() <= 0 || !compareRawSize(usageVOS.get(0), oneLoadStation)) { |
| | | |
| | | // 检查上片机是否正在工作,若正在工作则不生成退回任务 |
| | | if (pattenUsageList.stream().allMatch(vo -> vo.getState() == 101)) { |
| | | log.warn("上片机{}正在工作,无法执行退回任务", stationCell); |
| | | return Boolean.FALSE; |
| | | } |
| | | |
| | | // 生成退回任务:101上片位 → 原仓库存储位 |
| | | rawGlassStorageDetailsService.generateTask( |
| | | stations.get(0).getSlot(), |
| | | oneLoadStation.getShelf(), |
| | | oneLoadStation.getShelf(), |
| | | oneLoadStation.getRemainQuantity(), |
| | | Const.RAW_GLASS_TASK_TYPE_DISPATCH); |
| | | |
| | | rawGlassStorageTaskService.update(new LambdaUpdateWrapper<RawGlassStorageTask>() |
| | | .eq(RawGlassStorageTask::getTaskType, Const.RAW_GLASS_TASK_TYPE_DISPATCH) |
| | | .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW) |
| | | .set(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING)); |
| | | |
| | | rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>() |
| | | .eq(RawGlassStorageDetails::getSlot, oneLoadStation.getSlot()) |
| | | .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN) |
| | | .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING)); |
| | | S7Data s7Data = new S7Data(); |
| | | s7Data.setTaskWord((short) 1); // 任务触发信号 |
| | | s7Data.setStartSlot((short) LOAD_STATION_01.get(0).intValue()); // 起始位:上片位101 |
| | | s7Data.setEndSlot((short) oneLoadStation.getShelf().intValue()); // 目标位:仓库 |
| | | s7Serializer.write(s7Data); // 发送到PLC |
| | | |
| | | log.info("退回任务已发送PLC:从上片位{}到仓库{}", LOAD_STATION_01, oneLoadStation.getShelf()); |
| | | return Boolean.FALSE; |
| | | } |
| | | // 上片位101玻璃尺寸匹配且数量充足 → 无需调度 |
| | | log.info("101工位玻璃尺寸匹配且数量充足,无需调度"); |
| | | return Boolean.FALSE; |
| | | } |
| | | |
| | | private ReadWriteEntity generateReadWriteEntity(String identifier, int value) { |
| | | ReadWriteEntity readWriteEntity = new ReadWriteEntity(); |
| | | readWriteEntity.setIdentifier(identifier); |
| | | readWriteEntity.setValue(value); |
| | | return readWriteEntity; |
| | | } |
| | | |
| | | private RawGlassStorageDetails getRawGlassStorageDetailsBySize(UpPattenUsageVO usageVO, int remainQuantity) { |
| | | return rawGlassStorageDetailsService.getOne(new LambdaQueryWrapper<RawGlassStorageDetails>() |
| | | .eq(RawGlassStorageDetails::getFilmsId, usageVO.getFilmsId()) |
| | | .eq(RawGlassStorageDetails::getPatternWidth, usageVO.getWidth()) |
| | | .eq(RawGlassStorageDetails::getPatternHeight, usageVO.getHeight()) |
| | | .eq(RawGlassStorageDetails::getPatternThickness, usageVO.getThickness()) |
| | | .notIn(RawGlassStorageDetails::getSlot, LOAD_STATION_01) |
| | | .eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN) |
| | | .orderByAsc(RawGlassStorageDetails::getRemainQuantity) |
| | | .last("order by abs(t.remain_quantity - " + remainQuantity + ") asc") |
| | | .last("limit 1")); |
| | | } |
| | | |
| | | /** |
| | | * 生成原片仓储任务 |
| | | * 尺寸一样并且原片数量大于0 |
| | | * |
| | | * @param startSlot |
| | | * @param endSlot |
| | | * @param patternQuantity |
| | | * @param taskType |
| | | * @param upPattenUsage |
| | | * @param details |
| | | * @return |
| | | */ |
| | | private boolean generateTask(int startSlot, int endSlot, Integer patternQuantity, int taskType) { |
| | | RawGlassStorageTask task = RawGlassStorageTask.builder() |
| | | .originateSlot(startSlot) |
| | | .endSlot(endSlot) |
| | | .patternQuantity(patternQuantity) |
| | | .taskType(taskType) |
| | | .createTime(new Date()).build(); |
| | | return rawGlassStorageTaskService.save(task); |
| | | private boolean compareRawSize(UpPattenUsage upPattenUsage, RawGlassStorageDetails details) { |
| | | boolean flag = upPattenUsage.getWidth() == details.getPatternWidth() && upPattenUsage.getHeight() == details.getPatternHeight() && |
| | | upPattenUsage.getThickness() == details.getPatternThickness() && upPattenUsage.getFilmsId().equals(details.getFilmsId()); |
| | | return flag; |
| | | } |
| | | |
| | | } |
| | | |