1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
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.toolkit.CollectionUtils;
import com.kangaroohy.milo.model.ReadWriteEntity;
import com.kangaroohy.milo.service.MiloService;
import com.mes.bigstorage.entity.BigStorageCage;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.entity.BigStorageDTO;
import com.mes.bigstorage.service.BigStorageCageDetailsService;
import com.mes.bigstorage.service.BigStorageCageService;
import com.mes.bigstoragecagetask.entity.BigStorageCageHistoryTask;
import com.mes.bigstoragecagetask.entity.BigStorageCageTask;
import com.mes.bigstoragecagetask.service.BigStorageCageHistoryTaskService;
import com.mes.bigstoragecagetask.service.BigStorageCageTaskService;
import com.mes.bigstoragetask.entity.UpdateBigStorageCageDTO;
import com.mes.common.config.Const;
import com.mes.damage.service.DamageService;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.temperingglass.service.TemperingGlassInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
 
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
 
/**
 * @author SNG-015
 */
@Component
@Slf4j
public class OpcPlcStorageCageTask {
    @Resource
    private BigStorageCageDetailsService bigStorageCageDetailsService;
    @Resource
    private TemperingGlassInfoService temperingGlassInfoService;
    @Resource
    private DamageService damageService;
 
    @Resource
    private GlassInfoService glassInfoService;
    @Resource
    private BigStorageCageService bigStorageCageService;
    @Resource
    private BigStorageCageHistoryTaskService bigStorageCageHistoryTaskService;
    @Resource
    private BigStorageCageTaskService bigStorageCageTaskService;
 
    @Autowired(required = false)
    MiloService miloService;
 
    @Value("${mes.slotWidth}")
    private Integer slotWidth;
 
    @Value("${mes.glassGap}")
    private Integer glassGap;
 
    @Scheduled(fixedDelay = 1000)
    public void inBigStorageTask() throws Exception {
        ReadWriteEntity inkageEntity = miloService.readFromOpcUa("PLC.DPL1.inkageState");
        if (!"1".equals(inkageEntity.getValue())) {
            log.info("当前为非联机状态,结束进片任务");
            return;
        }
        ReadWriteEntity requestEntity = miloService.readFromOpcUa("PLC.DPL1.plcInGlassRequest");
        if (!"1".equals(requestEntity.getValue())) {
            log.info("当前未收到进片请求,结束进片任务");
            return;
        }
        //获取进片任务表
        List<BigStorageCageTask> inTaskList = bigStorageCageTaskService.queryTaskMessage("big_storage_cage_in_one_task");
        if (CollectionUtils.isEmpty(inTaskList)) {
            log.info("当前大车无进片玻璃,结束进片任务");
        }
        List<String> glassIdList = inTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList());
        log.info("获取任务的玻璃id:{}", glassIdList);
        Map<String, List<BigStorageCageTask>> taskMap = inTaskList.stream().collect(Collectors.groupingBy(BigStorageCageTask::getGlassId));
        List<GlassInfo> glassInfoList = glassInfoService.list(new LambdaQueryWrapper<GlassInfo>().in(GlassInfo::getGlassId, glassIdList));
        //计算目标格子
        List<BigStorageCageHistoryTask> historyTasks = new ArrayList<>();
        for (GlassInfo info : glassInfoList) {
            //获取目标格子信息
            BigStorageDTO bigStorageDTO = bigStorageCageDetailsService.queryTargetSlotByTempering(info);
//            临时更新格子的剩余尺寸:防止相邻玻璃进同一格子造成剩余尺寸不足,玻璃越界的情况,任务完成后再次更新大理片笼表剩余宽度(按照笼内玻璃数量更新大理片笼剩余尺寸)
            bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>()
                    .set(BigStorageCage::getRemainWidth, bigStorageDTO.getWidth() - Math.max(info.getWidth(), info.getHeight()) - glassGap)
                    .eq(BigStorageCage::getSlot, bigStorageDTO.getSlot()));
            BigStorageCageTask task = taskMap.get(info.getGlassId()).get(0);
            task.setTargetSlot(bigStorageDTO.getSlot());
            task.setGlassId(info.getGlassId());
            bigStorageCageTaskService.updateTaskMessage("big_storage_cage_in_one_task", task);
            //存放历史任务
            BigStorageCageHistoryTask historyTask = new BigStorageCageHistoryTask();
            BeanUtils.copyProperties(task, historyTask);
            historyTask.setTaskType(Const.BIG_STORAGE_BEFORE_IN);
            historyTask.setGlassCount(glassInfoList.size());
            historyTask.setTaskState(Const.ENGINEERING_NEW);
 
            BigStorageCageDetails cageDetails = new BigStorageCageDetails();
            BeanUtils.copyProperties(info, cageDetails);
            cageDetails.setSlot(bigStorageDTO.getSlot());
            cageDetails.setState(Const.GLASS_STATE_NEW);
            cageDetails.setDeviceId(bigStorageDTO.getDeviceId());
            cageDetails.setGap(glassGap);
            bigStorageCageDetailsService.save(cageDetails);
        }
        //历史数据入库
        bigStorageCageHistoryTaskService.saveBatch(historyTasks);
        //向opc发送启动信号
        miloService.writeToOpcWord(generateReadWriteEntity("PLC.DPL1.taskRunning", 1));
    }
 
    @Scheduled(fixedDelay = 1000)
    public void finishBigStorageTask() throws Exception {
        ReadWriteEntity inkageEntity = miloService.readFromOpcUa("PLC.DPL1.inkageState");
        if (!"1".equals(inkageEntity.getValue())) {
            log.info("当前为非联机状态,结束完成进片任务");
            return;
        }
        //获取进片任务表
        List<BigStorageCageTask> inTaskList = bigStorageCageTaskService.queryTaskMessage("big_storage_cage_in_one_task");
        if (CollectionUtils.isEmpty(inTaskList)) {
            log.info("当前大车无进片玻璃,结束完成进片任务");
        }
        List<BigStorageCageTask> unFinishTaskList = inTaskList.stream().filter(e -> e.getTaskState() <= 1).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(unFinishTaskList)) {
            log.info("存在未完成的玻璃信息,玻璃:{}", unFinishTaskList);
            return;
        }
        Map<Integer, List<BigStorageCageTask>> taskMap = inTaskList.stream().collect(Collectors.groupingBy(BigStorageCageTask::getTaskState));
        //按照任务状态修改大理片笼内的玻璃数据
        taskMap.forEach((e1, v) -> {
            List<String> glassList = v.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList());
            if (e1 == 2) {
                //进片完成
                log.info("3、获取进片已完成的玻璃信息id:{}", v);
                List<Integer> inSuccessGlassSlot = v.stream().map(BigStorageCageTask::getTargetSlot).collect(Collectors.toList());
                List<UpdateBigStorageCageDTO> storageCageDTOList = v.stream().map(e -> {
                    UpdateBigStorageCageDTO storageCageDTO = new UpdateBigStorageCageDTO();
                    BeanUtils.copyProperties(e, storageCageDTO);
                    return storageCageDTO;
                }).collect(Collectors.toList());
                bigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_IN);
                log.info("4、大理片笼进片状态已完成已完成的玻璃信息id:{}", v);
                updateSlotRemainBySlots(inSuccessGlassSlot);
            } else if (e1 == 3) {
                //破损处理
            } else {
                //清空理片笼空数据
            }
        });
        //todo:按照任务状态修改大理片笼内的玻璃数据
        //todo:重新计算大理片笼内的剩余尺寸
        //todo:更新历史任务表中的任务状态
        //todo:清空任务表数据
        //todo:清空启动状态
 
    }
 
//
//    @Scheduled(fixedDelay = 300)
//    public void updateOutGlassStateTask() {
//        Date startDate = new Date();
//        log.info("1、大理片笼出片完成后更新大理片笼数据任务开始执行时间:{}", startDate);
//        //因为大理片笼和出片任务是两个库的数据,所以要分开查找
//        List<Object> list = bigStorageCageDetailsService.listObjs(new LambdaQueryWrapper<BigStorageCageDetails>()
//                .select(BigStorageCageDetails::getGlassId).eq(BigStorageCageDetails::getState, Const.GLASS_STATE_OUT_ING));
//        if (CollectionUtils.isNotEmpty(list)) {
//            log.info("2、获取所有正在出片的玻璃信息id:{}", list);
//            List<String> glassIds = list.stream().map(String::valueOf).collect(Collectors.toList());
//            List<BigStorageCageOutTask> outSuccessGlass = bigStorageCageOutTaskService.list(new LambdaQueryWrapper<BigStorageCageOutTask>()
//                    .in(BigStorageCageOutTask::getGlassId, glassIds).in(BigStorageCageOutTask::getTaskState, Const.BIG_STORAGE_OUT_ALL));
//            if (CollectionUtils.isNotEmpty(outSuccessGlass)) {
//                for (BigStorageCageOutTask bigStorageCageOutTask : outSuccessGlass
//                ) {
//                    if (bigStorageCageOutTask.getEndSlot().equals(Const.ARTIFICIAL_OUT_TARGET_POSITION)) {
//                        temperingGlassInfoService.update(
//                                new LambdaUpdateWrapper<TemperingGlassInfo>()
//                                        .set(TemperingGlassInfo::getState, Const.TEMPERING_END)
//                                        .eq(TemperingGlassInfo::getGlassId, bigStorageCageOutTask.getGlassId())
//                        );
//                    }
//                }
//                log.info("3、获取出片已完成的玻璃信息id:{}", outSuccessGlass);
//                List<UpdateBigStorageCageDTO> storageCageDTOList = outSuccessGlass.stream().map(e -> {
//                    UpdateBigStorageCageDTO storageCageDTO = new UpdateBigStorageCageDTO();
//                    storageCageDTO.setGlassId(e.getGlassId());
//                    storageCageDTO.setTargetSlot(e.getStartSlot());
//                    return storageCageDTO;
//                }).collect(Collectors.toList());
//                bigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_OUT);
//                List<Integer> outSuccessSlotList = outSuccessGlass.stream().map(BigStorageCageOutTask::getStartSlot).collect(Collectors.toList());
//                log.info("4、大理片笼出片状态已完成已完成的玻璃信息id:{}", outSuccessGlass);
//                //更新理片笼玻璃尺寸
//                baseService.updateSlotRemainBySlots(outSuccessSlotList);
//                log.info("5、大理片笼进片目标格子尺寸更新完成");
//            }
//        }
//        Date endDate = new Date();
//        log.info("end:大理片笼出片完成后更新大理片笼数据任务结束时间:{},共耗时:{}ms,结束任务", endDate, endDate.getTime() - startDate.getTime());
//        return;
//
//    }
//
//    @Scheduled(fixedDelay = 300)
//    public void updateScheduleGlassStateTask() {
//        Date startDate = new Date();
//        log.info("1、大理片笼调度完成后更新大理片笼数据任务开始执行时间:{}", startDate);
//        //因为大理片笼和调度任务是两个库的数据,所以要分开查找
//        List<Object> list = bigStorageCageDetailsService.listObjs(new LambdaQueryWrapper<BigStorageCageDetails>()
//                .select(BigStorageCageDetails::getGlassId).eq(BigStorageCageDetails::getState, Const.GLASS_STATE_SCHEDULE_ING));
//        if (CollectionUtils.isNotEmpty(list)) {
//            log.info("2、获取所有正在出片的玻璃信息id:{}", list);
//            List<String> glassIds = list.stream().map(String::valueOf).collect(Collectors.toList());
//            List<BigStorageCageOutTask> scheduleSuccessGlass = bigStorageCageOutTaskService.list(new LambdaQueryWrapper<BigStorageCageOutTask>()
//                    .in(BigStorageCageOutTask::getGlassId, glassIds).eq(BigStorageCageOutTask::getTaskState, Const.BIG_STORAGE_OUT_SUCCESS)
//                    .notIn(BigStorageCageOutTask::getEndSlot, Const.TEMPERING_OUT_TARGET_POSITION, Const.ARTIFICIAL_OUT_TARGET_POSITION));
//            if (CollectionUtils.isNotEmpty(scheduleSuccessGlass)) {
//                log.info("3、获取调度已完成的玻璃信息id:{}", scheduleSuccessGlass);
//                List<UpdateBigStorageCageDTO> storageCageDTOList = scheduleSuccessGlass.stream().map(e -> {
//                    UpdateBigStorageCageDTO storageCageDTO = new UpdateBigStorageCageDTO();
//                    storageCageDTO.setGlassId(e.getGlassId());
//                    storageCageDTO.setTargetSlot(e.getEndSlot());
//                    return storageCageDTO;
//                }).collect(Collectors.toList());
//                bigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_IN);
//                List<String> scheduleSuccessGlassIds = scheduleSuccessGlass.stream().map(BigStorageCageOutTask::getGlassId).collect(Collectors.toList());
//                log.info("4、大理片笼出片状态已完成已完成的玻璃信息id:{}", scheduleSuccessGlassIds);
//                //更新理片笼玻璃尺寸
//                List<Integer> slotList = scheduleSuccessGlass.stream().map(BigStorageCageOutTask::getStartSlot).distinct().collect(Collectors.toList());
//                slotList.addAll(scheduleSuccessGlass.stream().map(BigStorageCageOutTask::getEndSlot).distinct().collect(Collectors.toList()));
//                baseService.updateSlotRemainBySlots(slotList);
//                log.info("5、大理片笼进片目标格子尺寸更新完成");
//            }
//        }
//        Date endDate = new Date();
//        log.info("end:大理片笼出片完成后更新大理片笼数据任务结束时间:{},共耗时:{}ms,结束任务", endDate, endDate.getTime() - startDate.getTime());
//        return;
//
//    }
//
//    /**
//     * 处理破损表任务
//     */
//    @Scheduled(fixedDelay = 300)
//    public void dealDamageTask() {
//        Date startDate = new Date();
//        log.info("大理片笼破损玻璃清除任务开始执行时间:{}", startDate);
//        //获取进片任务表中状态为破损的数据
//        List<BigStorageCageFeedTask> inDamageTaskInfoList = bigStorageCageFeedTaskService.list(new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                .in(BigStorageCageFeedTask::getTaskState, Const.GLASS_STATE_DAMAGE_TAKE));
//        if (CollectionUtils.isNotEmpty(inDamageTaskInfoList)) {
//            log.info("获取进片任务表中破损的玻璃信息{}", inDamageTaskInfoList);
//            bigStorageCageFeedTaskService.remove(new LambdaQueryWrapper<BigStorageCageFeedTask>().in(BigStorageCageFeedTask::getTaskState, Const.GLASS_STATE_DAMAGE_TAKE));
//            //理片笼详情表数据状态更新
//            bigStorageCageDetailsService.remove(new LambdaQueryWrapper<BigStorageCageDetails>()
//                    .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_NEW).in(BigStorageCageDetails::getGlassId, inDamageTaskInfoList.stream().map(BigStorageCageFeedTask::getGlassId).collect(Collectors.toList())));
//            //将破损信息新增入破损表
//            List<Integer> slotList = new ArrayList<>();
//            for (BigStorageCageFeedTask bigStorageCageFeedTask : inDamageTaskInfoList) {
//                Damage damage = new Damage();
//                damage.setGlassId(bigStorageCageFeedTask.getGlassId());
//                damage.setLine(bigStorageCageFeedTask.getLine());
//                damage.setWorkingProcedure("磨边");
//                damage.setRemark("进笼前卧转立");
//                damage.setStatus(1);
//                damage.setType(bigStorageCageFeedTask.getTaskState());
//                damageService.insertDamage(damage);
//                slotList.add(bigStorageCageFeedTask.getTargetSlot());
//            }
//            //更新格子剩余宽度
//            baseService.updateSlotRemainBySlots(slotList);
//            log.info("进片任务执行完成");
//        }
//        //获取出片任务表中状态为破损的数据
//        List<BigStorageCageOutTask> outDamageTaskInfoList = bigStorageCageOutTaskService.list(new LambdaQueryWrapper<BigStorageCageOutTask>()
//                .in(BigStorageCageOutTask::getTaskState, Const.GLASS_STATE_DAMAGE_TAKE));
//        if (CollectionUtils.isNotEmpty(outDamageTaskInfoList)) {
//            log.info("获取出片任务表中破损的玻璃信息{}", outDamageTaskInfoList);
//            bigStorageCageOutTaskService.remove(new LambdaQueryWrapper<BigStorageCageOutTask>().in(BigStorageCageOutTask::getTaskState, Const.GLASS_STATE_DAMAGE_TAKE));
//            List<String> glassIdList = outDamageTaskInfoList.stream().map(BigStorageCageOutTask::getGlassId).collect(Collectors.toList());
//            //移除钢化下片表数据
//            temperingGlassInfoService.remove(new LambdaQueryWrapper<TemperingGlassInfo>().in(TemperingGlassInfo::getGlassId, glassIdList));
//            //理片笼详情表数据状态删除
//            bigStorageCageDetailsService.remove(new LambdaQueryWrapper<BigStorageCageDetails>().in(BigStorageCageDetails::getGlassId, glassIdList));
//            //将破损信息新增入破损表
//            List<Integer> slotList = new ArrayList<>();
//            for (BigStorageCageOutTask bigStorageCageOutTask : outDamageTaskInfoList) {
//                Damage damage = new Damage();
//                damage.setGlassId(bigStorageCageOutTask.getGlassId());
//                damage.setLine(bigStorageCageOutTask.getEndSlot());
//                damage.setWorkingProcedure("钢化");
//                damage.setRemark("出片后卧转立");
//                damage.setStatus(1);
//                damage.setType(bigStorageCageOutTask.getTaskState());
//                damageService.insertDamage(damage);
//                slotList.add(bigStorageCageOutTask.getStartSlot());
//            }
//            //更新格子剩余宽度
//            baseService.updateSlotRemainBySlots(slotList);
//            log.info("出片任务执行完成");
//        }
//        Date endDate = new Date();
//        log.info("大理片笼破损玻璃清除任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//        return;
//    }
 
    public void updateSlotRemainBySlots(List<Integer> slotList) {
        //获取格子内所有的玻璃信息
        List<BigStorageCageDetails> inSlotGlassList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                .in(BigStorageCageDetails::getSlot, slotList).in(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL));
        Map<Integer, Double> slotRemainMap = new HashMap<>();
        //是否存在有格子非空的玻璃
        if (CollectionUtils.isNotEmpty(inSlotGlassList)) {
            //存在  将格子内的玻璃分别进行更新
            slotRemainMap = inSlotGlassList.stream()
                    .collect(Collectors.groupingBy(BigStorageCageDetails::getSlot, Collectors.summingDouble(item -> Math.max(item.getWidth(), item.getHeight()) + glassGap)));
            slotRemainMap.forEach((e, v) -> {
                double remainWidth = slotWidth - v >= 0 ? slotWidth - v : 0;
                bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, remainWidth)
                        .eq(BigStorageCage::getSlot, e));
            });
        }
        //过滤不存在玻璃的格子 将宽度重置为原始宽度5000
        Set<Integer> remainSlotList = slotRemainMap.keySet();
        slotList.removeAll(remainSlotList);
        if (CollectionUtils.isNotEmpty(slotList)) {
            bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, slotWidth)
                    .in(BigStorageCage::getSlot, slotList));
        }
    }
 
    private ReadWriteEntity generateReadWriteEntity(String identifier, Object value) {
        return ReadWriteEntity.builder()
                .identifier(identifier)
                //Kep中是Long类型,即:Int32,Java中的int类型
                .value(value)
                .build();
    }
}