package com.mes.job; import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; 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.rawglassdetails.entity.RawGlassStorageDetails; import com.mes.rawglassdetails.service.RawGlassStorageDetailsService; import com.mes.rawglassstation.service.RawGlassStorageStationService; import com.mes.rawglasstask.entity.RawGlassStorageTask; import com.mes.rawglasstask.service.RawGlassStorageTaskService; import com.mes.uppattenusage.entity.vo.UpPattenUsageVO; import com.mes.uppattenusage.mapper.UpPattenUsageMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; /** * @Author : zhoush * @Date: 2024/10/11 16:13 * @Description: */ @Slf4j @Component public class RawGlassTask { @Autowired private RawGlassStorageStationService rawGlassStorageStationService; @Autowired private RawGlassStorageDetailsService rawGlassStorageDetailsService; @Autowired private RawGlassStorageTaskService rawGlassStorageTaskService; @Resource private EngineeringMapper engineeringMapper; @Resource private UpPattenUsageMapper upPattenUsageMapper; @Autowired(required = false) private MiloService miloService; private static final List LIFTING_STATION = Arrays.asList(4); private static final List LOAD_STATION_01 = Arrays.asList("101", "102"); private static final List LOAD_STATION_02 = Arrays.asList("103", "104"); private static final List LOAD_STATION_MAX = Arrays.asList(102, 104); @Scheduled(fixedDelay = 1000) public void rawStorageTask() throws Exception { ReadWriteEntity requestWord = miloService.readFromOpcUa("storage-device.dev.Task Request"); ReadWriteEntity confireWord = miloService.readFromOpcUa("storage-device.dev.Task Confirmation Word"); ReadWriteEntity taskWord = miloService.readFromOpcUa("storage-device.dev.Task sending word"); String requestValue = requestWord.getValue() + ""; if ("0".equals(requestValue)) { if ("1".equals(confireWord.getValue() + "")) { List list = new ArrayList<>(); list.add(generateReadWriteEntity("storage-device.dev.Task Confirmation Word", 0)); miloService.writeToOpcWord(list); } if ("1".equals(taskWord.getValue() + "")) { List list = new ArrayList<>(); list.add(generateReadWriteEntity("storage-device.dev.Task sending word", 0)); list.add(generateReadWriteEntity("storage-device.dev.Task distribution", 0)); list.add(generateReadWriteEntity("storage-device.dev.Starting material rack number", 0)); list.add(generateReadWriteEntity("storage-device.dev.End shelf number", 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 = outboundTask(); if (flag) { log.info("执行出库任务,结束"); return; } flag = warehouseTask(); if (flag) { log.info("执行入库任务"); return; } log.info("无任务执行,结束"); } @Scheduled(fixedDelay = 1000) public void rawStorageInCar() throws Exception { ReadWriteEntity entity = miloService.readFromOpcUa("storage-device.dev.Loading rack"); String value = entity.getValue() + ""; if (!"1".equals(value)) { log.info("大车忙碌"); return; } //查询任务 RawGlassStorageDetails one = rawGlassStorageDetailsService.getOne(new LambdaQueryWrapper() .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING)); if (one == null) { return; } rawGlassStorageDetailsService.update(new LambdaUpdateWrapper().eq(RawGlassStorageDetails::getId, one.getId()) .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_CAR)); } @Scheduled(fixedDelay = 1000) public void rawStorageFinish() throws Exception { ReadWriteEntity entity = miloService.readFromOpcUa("storage-device.dev.Task report letter"); String value = entity.getValue() + ""; if ("0".equals(value)) { log.info("当前任务未汇报,结束本次任务"); return; } RawGlassStorageDetails details = rawGlassStorageDetailsService.getOne(new LambdaUpdateWrapper() .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_CAR)); if (null == details) { log.info("无执行中的任务"); return; } RawGlassStorageTask task = rawGlassStorageTaskService.getOne(new LambdaQueryWrapper() .in(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW)); RawGlassStorageDetails targetDetails = generateDetails(details, task.getEndSlot()); Integer taskType = task.getTaskType(); if ("1".equals(value)) { switch (taskType) { case 1: log.info("进片任务"); rawGlassStorageDetailsService.update(new LambdaUpdateWrapper() .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_OUT) .eq(RawGlassStorageDetails::getSlot, task.getStartSlot()).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_CAR)); //todo:生成入库详情表:其他信息不变, rawGlassStorageDetailsService.save(targetDetails); break; case 2: log.info("出片任务"); rawGlassStorageDetailsService.update(new LambdaUpdateWrapper() .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_OUT) .eq(RawGlassStorageDetails::getSlot, task.getStartSlot()) .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_CAR)); targetDetails = new RawGlassStorageDetails(); targetDetails.setSlot(task.getEndSlot()); targetDetails.setShelf(task.getStartSlot()); targetDetails.setState(Const.RAW_GLASS_STATE_IN); rawGlassStorageDetailsService.save(targetDetails); break; case 3: log.info("调度任务"); rawGlassStorageDetailsService.update(new LambdaUpdateWrapper() .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_OUT) .eq(RawGlassStorageDetails::getSlot, task.getStartSlot()).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_CAR)); rawGlassStorageDetailsService.save(targetDetails); break; default: break; } rawGlassStorageTaskService.update(new LambdaUpdateWrapper() .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW) .set(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_SUCCESS)); } else { rawGlassStorageTaskService.update(new LambdaUpdateWrapper() .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW) .set(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_FAILURE)); rawGlassStorageDetailsService.update(new LambdaUpdateWrapper() .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN) .eq(RawGlassStorageDetails::getSlot, task.getStartSlot()).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_CAR)); } List list = new ArrayList<>(); list.add(generateReadWriteEntity("storage-device.dev.Task Confirmation Word", 1)); miloService.writeToOpcWord(list); } private boolean isHasRunningTask() { RawGlassStorageTask task = rawGlassStorageTaskService.getOne(new LambdaQueryWrapper() .in(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW)); return task == null ? Boolean.FALSE : Boolean.TRUE; } /** * 原片调度:1、查询工程原片表,按照顺序将原片放入上片1号位,后续原片放上片2号位,出现尺寸替换,判断原上片位是否有玻璃,有 先出后进,无 直接进片 */ public boolean rawGlassDispatchTask() throws Exception { //查询当前系统正在执行的订单 List engineeringList = engineeringMapper.selectList(new LambdaQueryWrapper() .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; } /** * 出库任务:1、点出库,立马生成出片任务 2、点出库修改工位详情内的状态为待出库,定时任务扫描生成出库任务 */ public boolean outboundTask() throws Exception { List rawGlassList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper() .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_WAIT_OUT)); // .inSql(RawGlassStorageDetails::getSlot, "select slot from raw_glass_storage_station where enable_state = 1 and device_id = 4")); if (CollectionUtil.isEmpty(rawGlassList)) { log.info("系统没有需要出库的原片信息"); return Boolean.FALSE; } //获取工位上是否有架子, List emptyLeftingList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper() .in(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN_ALL) .in(RawGlassStorageDetails::getSlot, 98, 99)); if (CollectionUtil.isNotEmpty(emptyLeftingList) && emptyLeftingList.size() >= 2) { log.info("吊装位当前都有架子,结束出片任务"); return Boolean.FALSE; } //获取需要落架的 //生成出库任务 rawGlassStorageDetailsService.generateTask(rawGlassList.get(0).getSlot(), 98, rawGlassList.get(0).getSlot(), rawGlassList.get(0).getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_OUT); List list = new ArrayList<>(); list.add(generateReadWriteEntity("storage-device.dev.Task sending word", 1)); list.add(generateReadWriteEntity("storage-device.dev.Task distribution", 1)); list.add(generateReadWriteEntity("storage-device.dev.Starting material rack number", rawGlassList.get(0).getSlot())); list.add(generateReadWriteEntity("storage-device.dev.End shelf number", 98)); miloService.writeToOpcWord(list); //修改出片任务状态 rawGlassStorageDetailsService.update(new LambdaUpdateWrapper() .eq(RawGlassStorageDetails::getSlot, rawGlassList.get(0).getSlot()) .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_WAIT_OUT) .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING)); return Boolean.TRUE; } /** * 入库任务:吊装位有玻璃,先去工位表查询空格子,生成入库任务从吊装位到目标格子 * * @throws Exception */ public boolean warehouseTask() throws Exception { List rawGlassList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper() .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; } //获取吊装位架子信息 // List shelfList = rawGlassList.stream().map(RawGlassStorageDetails::getShelf).collect(Collectors.toList()); // List stationList = rawGlassStorageStationService.list(new LambdaQueryWrapper().notInSql(RawGlassStorageStation::getSlot, "select slot from raw_glass_storage_details where " + // "state in('100','102','103')") // .eq(RawGlassStorageStation::getEnableState, Const.SLOT_ON) // .in(RawGlassStorageStation::getDeviceId, Const.RAW_GLASS_DEVICE)); // if (CollectionUtil.isEmpty(stationList)) { // log.info("没有空的工位"); // return Boolean.FALSE; // } //生成进笼任务 RawGlassStorageDetails details = rawGlassList.get(0); rawGlassStorageDetailsService.generateTask(details.getSlot(), details.getShelf(), details.getShelf(), details.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_IN); List list = new ArrayList<>(); list.add(generateReadWriteEntity("storage-device.dev.Task sending word", 1)); list.add(generateReadWriteEntity("storage-device.dev.Task distribution", 1)); list.add(generateReadWriteEntity("storage-device.dev.Starting material rack number", details.getSlot())); list.add(generateReadWriteEntity("storage-device.dev.End shelf number", details.getShelf())); miloService.writeToOpcWord(list); //生成工位任务,将吊装位的玻璃状态改位进笼中 // 修改吊装位的原片状态为103 出片中 //修改出片任务状态 rawGlassStorageDetailsService.update(new LambdaUpdateWrapper() .eq(RawGlassStorageDetails::getSlot, rawGlassList.get(0).getSlot()) .eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN) .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING)); return Boolean.TRUE; } private boolean rawGlassDispatchByEngineering(String stationCell, String enginneerId) throws Exception { //当前尺寸需要上片的数量 List pattenUsageList = upPattenUsageMapper.queryRawGlassByEngineeringId(enginneerId); if (CollectionUtils.isEmpty(pattenUsageList)) { log.info("正在执行的工程原片无可上片的原片信息"); return Boolean.FALSE; } Map> upListMap = pattenUsageList.stream() .collect(Collectors.groupingBy(UpPattenUsageVO::getGroupNumber)); //1、查询2个上片的原片详情 List rawGlassDetailsList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper() .eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN).in(RawGlassStorageDetails::getDeviceId, stationCell) .orderByAsc(RawGlassStorageDetails::getSlot)); List upPattenUsage01VOS = upListMap.get("1"); UpPattenUsageVO usageVO = upPattenUsage01VOS.get(0); if (CollectionUtils.isEmpty(rawGlassDetailsList)) { //表示1上片位没有架子,直接找原片放入对应路线的1号上片位 RawGlassStorageDetails details = rawGlassStorageDetailsService.getOne(new LambdaQueryWrapper() .eq(RawGlassStorageDetails::getFilmsId, usageVO.getFilmsId()) .eq(RawGlassStorageDetails::getPatternWidth, usageVO.getWidth()) .eq(RawGlassStorageDetails::getPatternHeight, usageVO.getHeight()) .eq(RawGlassStorageDetails::getPatternThickness, usageVO.getThickness()) // .gt(RawGlassStorageDetails::getRemainQuantity, upPattenUsage01VOS.size()) .orderByAsc(RawGlassStorageDetails::getRemainQuantity) .last("limit 1") ); rawGlassStorageDetailsService.generateTask(details.getSlot(), rawGlassDetailsList.get(0).getSlot(), details.getSlot(), details.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH); List list = new ArrayList<>(); list.add(generateReadWriteEntity("storage-device.dev.Task sending word", 1)); list.add(generateReadWriteEntity("storage-device.dev.Task distribution", 1)); list.add(generateReadWriteEntity("storage-device.dev.Starting material rack number", details.getSlot())); list.add(generateReadWriteEntity("storage-device.dev.End shelf number", rawGlassDetailsList.get(0).getSlot())); miloService.writeToOpcWord(list); //结束调度任务 修改工位状态(起始位)状态为103 RAW_GLASS_STATE_RUNNING 任务完成后将状态改为101 目标位新增一条数据,架子号为(起始位) rawGlassStorageDetailsService.update(new LambdaUpdateWrapper() .eq(RawGlassStorageDetails::getShelf, details.getShelf()).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN) .set(RawGlassStorageDetails::getDeviceId, Const.RAW_GLASS_STATE_RUNNING)); return Boolean.TRUE; } if (rawGlassDetailsList.size() == 2) { RawGlassStorageDetails glassStorageDetails = rawGlassDetailsList.get(0); if (usageVO.getWidth() == glassStorageDetails.getPatternWidth() && usageVO.getHeight() == glassStorageDetails.getPatternHeight() && usageVO.getThickness() == glassStorageDetails.getPatternThickness() && usageVO.getFilmsId().equals(glassStorageDetails.getFilmsId())) { if (glassStorageDetails.getRemainQuantity() == 0) { //将架子放回原工位上 rawGlassStorageDetailsService.generateTask(glassStorageDetails.getSlot(), glassStorageDetails.getShelf(), glassStorageDetails.getShelf(), glassStorageDetails.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH); List list = new ArrayList<>(); list.add(generateReadWriteEntity("storage-device.dev.Task sending word", 1)); list.add(generateReadWriteEntity("storage-device.dev.Task distribution", 1)); list.add(generateReadWriteEntity("storage-device.dev.Starting material rack number", glassStorageDetails.getSlot())); list.add(generateReadWriteEntity("storage-device.dev.End shelf number", glassStorageDetails.getShelf())); miloService.writeToOpcWord(list); rawGlassStorageDetailsService.update(new LambdaUpdateWrapper() .eq(RawGlassStorageDetails::getSlot, glassStorageDetails.getSlot()).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN) .set(RawGlassStorageDetails::getDeviceId, Const.RAW_GLASS_STATE_RUNNING)); return Boolean.TRUE; } } log.info("上片位都有架子,结束本条线{}的调度任务", stationCell); return Boolean.FALSE; } RawGlassStorageDetails glassStorageDetails = rawGlassDetailsList.get(0); if (LOAD_STATION_MAX.contains(glassStorageDetails.getSlot())) { log.info("上片位2号有架子,结束本条线{}的调度任务", stationCell); return Boolean.FALSE; } //比较当前1号架子上的玻璃剩余数量是否为0或者已用完 if (usageVO.getWidth() == glassStorageDetails.getPatternWidth() && usageVO.getHeight() == glassStorageDetails.getPatternHeight() && usageVO.getThickness() == glassStorageDetails.getPatternThickness() && usageVO.getFilmsId().equals(glassStorageDetails.getFilmsId())) { RawGlassStorageDetails details = null; if (upPattenUsage01VOS.size() > glassStorageDetails.getRemainQuantity()) { //2号位上片:继续当前尺寸的原片 details = rawGlassStorageDetailsService.getOne(new LambdaQueryWrapper() .eq(RawGlassStorageDetails::getFilmsId, usageVO.getFilmsId()) .eq(RawGlassStorageDetails::getPatternWidth, usageVO.getWidth()) .eq(RawGlassStorageDetails::getPatternHeight, usageVO.getHeight()) .eq(RawGlassStorageDetails::getPatternThickness, usageVO.getThickness()) .gt(RawGlassStorageDetails::getRemainQuantity, upPattenUsage01VOS.size()) .orderByAsc(RawGlassStorageDetails::getRemainQuantity) .last("limit 1")); } else { //2号位上片:获取第二种尺寸的原片 List upPattenUsage02VOS = upListMap.get("2"); if (CollectionUtils.isEmpty(upPattenUsage01VOS)) { return Boolean.FALSE; } usageVO = upPattenUsage02VOS.get(0); details = rawGlassStorageDetailsService.getOne(new LambdaQueryWrapper() .eq(RawGlassStorageDetails::getFilmsId, usageVO.getFilmsId()) .eq(RawGlassStorageDetails::getPatternWidth, usageVO.getWidth()) .eq(RawGlassStorageDetails::getPatternHeight, usageVO.getHeight()) .eq(RawGlassStorageDetails::getPatternThickness, usageVO.getThickness()) .gt(RawGlassStorageDetails::getRemainQuantity, upPattenUsage01VOS.size()) .orderByAsc(RawGlassStorageDetails::getRemainQuantity) .last("limit 1")); } //将工位的架子传送到上片位 rawGlassStorageDetailsService.generateTask(details.getShelf(), glassStorageDetails.getSlot(), details.getShelf(), details.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH); rawGlassStorageDetailsService.update(new LambdaUpdateWrapper() .eq(RawGlassStorageDetails::getSlot, glassStorageDetails.getSlot()).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN) .set(RawGlassStorageDetails::getDeviceId, Const.RAW_GLASS_STATE_RUNNING)); List list = new ArrayList<>(); list.add(generateReadWriteEntity("storage-device.dev.Task sending word", 1)); list.add(generateReadWriteEntity("storage-device.dev.Task distribution", 1)); list.add(generateReadWriteEntity("storage-device.dev.Starting material rack number", glassStorageDetails.getShelf())); list.add(generateReadWriteEntity("storage-device.dev.End shelf number", glassStorageDetails.getSlot())); miloService.writeToOpcWord(list); return Boolean.TRUE; } else { //将架子放回原工位上 rawGlassStorageDetailsService.generateTask(0, glassStorageDetails.getShelf(), glassStorageDetails.getShelf(), glassStorageDetails.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH); rawGlassStorageDetailsService.update(new LambdaUpdateWrapper() .eq(RawGlassStorageDetails::getSlot, glassStorageDetails.getSlot()).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN) .set(RawGlassStorageDetails::getDeviceId, Const.RAW_GLASS_STATE_RUNNING)); List list = new ArrayList<>(); list.add(generateReadWriteEntity("storage-device.dev.Task sending word", 1)); list.add(generateReadWriteEntity("storage-device.dev.Task distribution", 1)); list.add(generateReadWriteEntity("storage-device.dev.Starting material rack number", glassStorageDetails.getShelf())); list.add(generateReadWriteEntity("storage-device.dev.End shelf number", glassStorageDetails.getSlot())); miloService.writeToOpcWord(list); return Boolean.TRUE; } } private RawGlassStorageDetails generateDetails(RawGlassStorageDetails details, Integer targetSlot) { RawGlassStorageDetails targetDetails = new RawGlassStorageDetails(); // details.setDeviceId(); targetDetails.setSlot(targetSlot); targetDetails.setShelf(details.getShelf()); targetDetails.setPatternWidth(details.getPatternWidth()); targetDetails.setPatternHeight(details.getPatternHeight()); targetDetails.setPatternThickness(details.getPatternThickness()); targetDetails.setFilmsId(details.getFilmsId()); targetDetails.setRemainQuantity(details.getRemainQuantity()); targetDetails.setCreateTime(new Date()); targetDetails.setState(Const.RAW_GLASS_STATE_IN); return targetDetails; } private ReadWriteEntity generateReadWriteEntity(String identifier, int value) { ReadWriteEntity readWriteEntity = new ReadWriteEntity(); readWriteEntity.setIdentifier(identifier); readWriteEntity.setValue(value); return readWriteEntity; } }