package com.mes.job;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.github.xingshuangs.iot.protocol.s7.serializer.S7Serializer;
|
import com.mes.common.config.Const;
|
import com.mes.engineering.entity.Engineering;
|
import com.mes.engineering.mapper.EngineeringMapper;
|
import com.mes.opctask.entity.LoadGlassDeviceTask;
|
import com.mes.opctask.entity.LoadGlassDeviceTaskHistory;
|
import com.mes.opctask.service.LoadGlassDeviceTaskHistoryService;
|
import com.mes.opctask.service.LoadGlassDeviceTaskService;
|
import com.mes.pp.entity.OptimizeProject;
|
import com.mes.pp.service.OptimizeProjectService;
|
import com.mes.rawglassdetails.entity.RawGlassStorageDetails;
|
import com.mes.rawglassdetails.service.RawGlassStorageDetailsService;
|
import com.mes.s7.entity.S7DataSP;
|
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.beans.BeanUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.stereotype.Component;
|
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.stream.Collectors;
|
|
/**
|
* @Author : zhoush
|
* @Date: 2024/10/23 14:30
|
* @Description:
|
*/
|
@Component
|
@Slf4j
|
public class OpcLoadGlassTask {
|
|
@Resource
|
private EngineeringMapper engineeringMapper;
|
|
@Resource
|
private LoadGlassDeviceTaskService loadGlassDeviceTaskService;
|
@Resource
|
private RawGlassStorageDetailsService rawGlassStorageDetailsService;
|
@Resource
|
private LoadGlassDeviceTaskHistoryService loadGlassDeviceTaskHistoryService;
|
@Resource
|
private UpPattenUsageMapper upPattenUsageMapper;
|
@Resource
|
private OptimizeProjectService optimizeProjectService;
|
|
@Autowired
|
@Qualifier("s7SerializerSP1")
|
private S7Serializer s7SerializerSPOne;
|
|
@Autowired
|
@Qualifier("s7SerializerSP2")
|
private S7Serializer s7SerializerSPTwo;
|
|
private static final List<Integer> LOAD_STATION_01 = Arrays.asList(101, 102);
|
private static final List<Integer> LOAD_STATION_02 = Arrays.asList(103, 104);
|
|
|
private static final Integer LOAD_GLASS_ONE_DEVICE = 5;
|
private static final Integer LOAD_GLASS_TWO_DEVICE = 6;
|
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";
|
|
//设备id 上片位信息 任务表不一致 历史任务表公用一张 新增任务/任务结束,后会在历史表中新增一条记录并在结束后更新任务 一个任务即可
|
//定时任务扫描上片位有没有原片
|
//1、是否有在执行的任务
|
//2、1号上片位是否有原片,原片尺寸是否和上片待上片的尺寸一致
|
//3、1号无原片,且没有架子,2号上片位尺寸是否和带上片尺寸一致
|
//4、不一致可能出现玻璃破损导致的上一架原片数量不够
|
@Scheduled(fixedDelay = 2000)
|
public void opcLoadGlassOne() {
|
opcLoadGlassChild(LOAD_GLASS_DEVICE_ONE_TASK, LOAD_GLASS_ONE_DEVICE);
|
}
|
|
// @Scheduled(fixedDelay = 5000)
|
public void opcLoadGlassTwo() {
|
opcLoadGlassChild(LOAD_GLASS_DEVICE_TWO_TASK, LOAD_GLASS_TWO_DEVICE);
|
}
|
|
@Scheduled(fixedDelay = 2000)
|
public void opcLoadGlassOneFinish() {
|
opcLoadGlassFinishChid(LOAD_GLASS_DEVICE_ONE_TASK, LOAD_GLASS_ONE_DEVICE);
|
}
|
|
// @Scheduled(fixedDelay = 5000)
|
public void opcLoadGlassTwoFinish() {
|
opcLoadGlassFinishChid(LOAD_GLASS_DEVICE_TWO_TASK, LOAD_GLASS_TWO_DEVICE);
|
}
|
|
/**
|
* 定时任务扫码已完成上片的工程,将工程状态改为已完成,同步pp表的工程表,状态改为300
|
*/
|
@Scheduled(fixedDelay = 5000)
|
public void updateEngineerState() {
|
log.info("修改已完成工程状态任务开始执行");
|
List<Engineering> engineerings = engineeringMapper.selectList(new LambdaQueryWrapper<Engineering>().eq(Engineering::getState, Const.ENGINEERING_RUNNING));
|
for (Engineering engineering : engineerings) {
|
Integer count = upPattenUsageMapper.selectCount(new LambdaQueryWrapper<UpPattenUsage>()
|
.eq(UpPattenUsage::getEngineeringId, engineering.getEngineerId()).ne(UpPattenUsage::getState, Const.LOAD_RAW_GLASS_SUCCESS));
|
OptimizeProject project = optimizeProjectService.getOne(new LambdaUpdateWrapper<OptimizeProject>()
|
.eq(OptimizeProject::getProjectNo, 200)
|
.eq(OptimizeProject::getState, engineering.getEngineerId()));
|
if (count == 0 && project != null) {
|
engineeringMapper.update(null, new LambdaUpdateWrapper<Engineering>().set(Engineering::getState, Const.ENGINEERING_SUCCESS)
|
.eq(Engineering::getEngineerId, engineering.getEngineerId()));
|
optimizeProjectService.update(null, new LambdaUpdateWrapper<OptimizeProject>().set(OptimizeProject::getState, 300)
|
.eq(OptimizeProject::getProjectNo, engineering.getEngineerId()));
|
}
|
}
|
}
|
|
private void opcLoadGlassChild(String tableName, Integer deviceId) {
|
S7DataSP s7DataSP = new S7DataSP();
|
// s7DataSP.setPlcRequest(1);
|
// s7DataSP.setMesConfirm(0);
|
if (tableName.equals(LOAD_GLASS_DEVICE_ONE_TASK)) {
|
s7DataSP = s7SerializerSPOne.read(S7DataSP.class);
|
} else {
|
s7DataSP = s7SerializerSPTwo.read(S7DataSP.class);
|
}
|
log.info("{}上片线,当前上片位信息:{}", deviceId, s7DataSP);
|
|
if (s7DataSP.getPlcRequest() == 0) {
|
if (s7DataSP.getMesSend() != 0) {
|
S7DataSP resetSend = new S7DataSP();
|
resetSend.setMesSend(0);
|
s7SerializerSPOne.write(resetSend);
|
log.info("{}上片线,PLC请求清零,MES同步清零mesSend", deviceId);
|
}
|
return;
|
}
|
|
// 当PLC请求新任务(plcRequest=1)且无未确认汇报(mesConfirm=0)时处理
|
if (s7DataSP.getPlcRequest() != 1 || s7DataSP.getMesConfirm() != 0) {
|
log.info("{}上片线,PLC未请求新任务或存在未确认汇报,跳过本次处理", deviceId);
|
return;
|
}
|
|
Engineering engineering = engineeringMapper.selectOne(new LambdaQueryWrapper<Engineering>()
|
.eq(Engineering::getState, Const.ENGINEERING_RUNNING)
|
.eq(Engineering::getStationCell, deviceId));
|
if (null == engineering) {
|
log.info("{}上片线,没有工程任务", deviceId);
|
return;
|
}
|
|
List<UpPattenUsageVO> pattenUsageList = upPattenUsageMapper.queryRawGlassByEngineeringId(engineering.getEngineerId());
|
log.info("获取正在需要上片的原片信息有:{}", pattenUsageList);
|
if (CollectionUtils.isEmpty(pattenUsageList)) {
|
log.info("当前工程需要上片的原片信息为空,任务已结束");
|
return;
|
}
|
// 有无正在执行的任务
|
UpPattenUsage runningTask = upPattenUsageMapper.selectOne(
|
new LambdaQueryWrapper<UpPattenUsage>()
|
.eq(UpPattenUsage::getEngineeringId, engineering.getEngineerId())
|
.eq(UpPattenUsage::getState, 101)
|
.last("limit 1") // 只取一条
|
);
|
if (runningTask != null) {
|
log.info("当前工程存在正在执行的上片任务,跳过本次处理");
|
return;
|
}
|
|
Map<String, List<UpPattenUsageVO>> upListMap = pattenUsageList.stream()
|
.collect(Collectors.groupingBy(UpPattenUsageVO::getGroupNumber));
|
log.info("获取当前需要上片的原片数据");
|
List<UpPattenUsageVO> usageVOS = upListMap.get("1");
|
// 获取1号上片位是有架子且有玻璃
|
List<Integer> loadStation = LOAD_GLASS_DEVICE_ONE_TASK.equals(tableName) ? LOAD_STATION_01 : LOAD_STATION_02;
|
List<RawGlassStorageDetails> loadStationList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>()
|
.inSql(RawGlassStorageDetails::getSlot, "select slot from raw_glass_storage_station where enable_state = 1")
|
.in(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN)
|
.eq(RawGlassStorageDetails::getDeviceId, deviceId));
|
if (CollectionUtils.isEmpty(loadStationList)) {
|
log.info("当前上片线路两个上片位都没有原片信息,结束本次上片任务,等待仓储调度任务");
|
return;
|
}
|
RawGlassStorageDetails oneLoadStation = loadStationList.stream().filter(e -> e.getSlot().equals(loadStation.get(0))).findFirst().orElse(null);
|
if (null == oneLoadStation) {
|
RawGlassStorageDetails twoLoadStation = loadStationList.stream().filter(e -> e.getSlot().equals(loadStation.get(1))).findFirst().orElse(null);
|
if (!compareRawSize(usageVOS.get(0), twoLoadStation)) {
|
log.info("二号上片位有架子,原片数量为0或者原片信息与待上片尺寸不一致,结束本次上片任务,等待仓储调度任务");
|
return;
|
}
|
int number = Math.min(twoLoadStation.getRemainQuantity(), usageVOS.size());
|
//生成上片任务
|
LoadGlassDeviceTaskHistory task = new LoadGlassDeviceTaskHistory();
|
task.setTotalCount(number);
|
task.setTaskRunning(1);
|
task.setRawGlassWidth((int) usageVOS.get(0).getWidth());
|
task.setRawGlassHeight((int) usageVOS.get(0).getHeight());
|
task.setSlot(1);
|
task.setRawGlassFilmsId(usageVOS.get(0).getFilmsId());
|
task.setEngineeringId(usageVOS.get(0).getEngineeringId());
|
saveHistoryTask(task, deviceId);
|
|
S7DataSP s7DataSPWrite = new S7DataSP();
|
s7DataSPWrite.setMesSend(1);
|
s7DataSPWrite.setRawGlassWidth((int) usageVOS.get(0).getWidth());
|
s7DataSPWrite.setRawGlassHeight((int) usageVOS.get(0).getHeight());
|
s7DataSPWrite.setSlot(1);
|
if (LOAD_GLASS_ONE_DEVICE.equals(deviceId)) {
|
s7SerializerSPOne.write(s7DataSPWrite);
|
} else {
|
s7SerializerSPTwo.write(s7DataSPWrite);
|
}
|
return;
|
}
|
//尺寸不一样或者原片数量大于0
|
if (!compareRawSize(usageVOS.get(0), oneLoadStation)) {
|
log.info("一号上片位有架子,原片数量为0或者原片信息与待上片尺寸不一致,结束本次上片任务,等待仓储调度任务");
|
return;
|
}
|
//生成上片任务
|
int number = Math.min(oneLoadStation.getRemainQuantity(), usageVOS.size());
|
LoadGlassDeviceTaskHistory task = new LoadGlassDeviceTaskHistory();
|
task.setTotalCount(number);
|
task.setTaskRunning(1);
|
task.setRawGlassWidth((int) usageVOS.get(0).getWidth());
|
task.setRawGlassHeight((int) usageVOS.get(0).getHeight());
|
task.setRawGlassThickness((int) usageVOS.get(0).getThickness());
|
task.setSlot(1);
|
task.setRawGlassFilmsId(usageVOS.get(0).getFilmsId());
|
task.setEngineeringId(usageVOS.get(0).getEngineeringId());
|
saveHistoryTask(task, deviceId);
|
|
UpPattenUsage upPattenUsage = upPattenUsageMapper.selectById(usageVOS.get(0).getId());
|
upPattenUsage.setState(101);
|
upPattenUsageMapper.updateById(upPattenUsage);
|
|
S7DataSP s7DataSPWrite = new S7DataSP();
|
s7DataSPWrite.setMesSend(1);
|
s7DataSPWrite.setRawGlassWidth((int) usageVOS.get(0).getWidth());
|
s7DataSPWrite.setRawGlassHeight((int) usageVOS.get(0).getHeight());
|
s7DataSPWrite.setSlot(1);
|
if (LOAD_GLASS_ONE_DEVICE.equals(deviceId)) {
|
s7SerializerSPOne.write(s7DataSPWrite);
|
} else {
|
s7SerializerSPTwo.write(s7DataSPWrite);
|
}
|
}
|
|
private void opcLoadGlassFinishChid(String tableName, Integer deviceId) {
|
S7DataSP s7DataSP = new S7DataSP();
|
// s7DataSP.setPlcReport(1);
|
// s7DataSP.setMesConfirm(0);
|
if (tableName.equals(LOAD_GLASS_DEVICE_ONE_TASK)) {
|
s7DataSP = s7SerializerSPOne.read(S7DataSP.class);
|
} else {
|
s7DataSP = s7SerializerSPTwo.read(S7DataSP.class);
|
}
|
log.info("{}上片线,当前上片位信息:{}", deviceId, s7DataSP);
|
|
if (s7DataSP.getPlcReport() == 0) {
|
if (s7DataSP.getMesConfirm() != 0) {
|
S7DataSP resetConfirm = new S7DataSP();
|
resetConfirm.setMesConfirm(0);
|
s7SerializerSPOne.write(resetConfirm);
|
log.info("{}上片线,PLC汇报清零,MES同步清零mesConfirm", deviceId);
|
}
|
return;
|
}
|
|
if (s7DataSP.getPlcReport() == 0 || s7DataSP.getMesConfirm() != 0) {
|
log.info("{}上片线,无PLC汇报或已确认,跳过本次处理", deviceId);
|
return;
|
}
|
LoadGlassDeviceTaskHistory unconfirmedTask = loadGlassDeviceTaskHistoryService.getOne(
|
new LambdaQueryWrapper<LoadGlassDeviceTaskHistory>()
|
.eq(LoadGlassDeviceTaskHistory::getStation, deviceId)
|
.eq(LoadGlassDeviceTaskHistory::getTaskState, Const.RAW_GLASS_TASK_RUNNING)
|
);
|
String upUsageId = unconfirmedTask.getEngineeringId();
|
if (s7DataSP.getPlcReport() == 1) {
|
// 汇报成功:更新上片记录为“成功”
|
upPattenUsageMapper.update(null,
|
new LambdaUpdateWrapper<UpPattenUsage>()
|
.set(UpPattenUsage::getState, Const.LOAD_RAW_GLASS_SUCCESS)
|
.eq(UpPattenUsage::getEngineeringId, upUsageId)
|
.eq(UpPattenUsage::getState, 101)
|
);
|
unconfirmedTask.setTaskState(Const.RAW_GLASS_TASK_SUCCESS);
|
unconfirmedTask.setFinishCount(unconfirmedTask.getFinishCount() + 1);
|
log.info("{}上片线,任务汇报成功,更新上片记录[{}]为成功", deviceId, upUsageId);
|
|
// PLC确认字1
|
s7DataSP.setMesConfirm(1);
|
s7SerializerSPOne.write(s7DataSP);
|
} else if (s7DataSP.getPlcReport() == 2) {
|
// 汇报失败
|
unconfirmedTask.setTaskState(2);
|
// unconfirmedTask.setDamageCount(unconfirmedTask.getDamageCount() + 1);
|
log.warn("{}上片线,任务汇报失败,上片记录[{}]标记为失败", deviceId, upUsageId);
|
|
// PLC确认字2
|
s7DataSP.setMesConfirm(2);
|
s7SerializerSPOne.write(s7DataSP);
|
}else if (s7DataSP.getPlcReport() == 3) {
|
// 汇报破损
|
unconfirmedTask.setTaskState(3);
|
unconfirmedTask.setDamageCount(unconfirmedTask.getDamageCount() + 1);
|
log.warn("{}上片线,任务汇报破损,上片记录[{}]标记为破损", deviceId, upUsageId);
|
|
// PLC确认字3
|
s7DataSP.setMesConfirm(3);
|
s7SerializerSPOne.write(s7DataSP);
|
}
|
unconfirmedTask.setUpdateTime(new Date());
|
loadGlassDeviceTaskHistoryService.updateById(unconfirmedTask);
|
|
//更新当前架子上的原片剩余情况
|
rawGlassStorageDetailsService.update(new UpdateWrapper<RawGlassStorageDetails>()
|
.inSql("slot", "select slot from raw_glass_storage_station where enable_state = 1")
|
// .eq("slot", task.getSlot())
|
.eq("slot", 101)
|
.eq("state", Const.RAW_GLASS_STATE_IN)
|
.setSql("remain_quantity = GREATEST(remain_quantity - 1, 0)"));
|
}
|
|
private boolean saveHistoryTask(LoadGlassDeviceTaskHistory task, Integer deviceId) {
|
LoadGlassDeviceTaskHistory taskHistory = new LoadGlassDeviceTaskHistory();
|
BeanUtils.copyProperties(task, taskHistory);
|
taskHistory.setStation(deviceId);
|
taskHistory.setCreateTime(new Date());
|
taskHistory.setTaskState(Const.RAW_GLASS_TASK_RUNNING);
|
loadGlassDeviceTaskHistoryService.save(taskHistory);
|
return Boolean.TRUE;
|
}
|
|
/**
|
* 尺寸一样并且原片数量大于0
|
*
|
* @param upPattenUsage
|
* @param details
|
* @return
|
*/
|
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 && details.getRemainQuantity() > 0;
|
}
|
|
}
|