zhoushihao
2024-10-27 ef45387ac4b65538bb965dd7fe9c40d28bceca64
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
348
349
350
351
352
353
354
355
356
357
package com.mes.job;
 
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.kangaroohy.milo.service.MiloService;
import com.mes.common.config.Const;
import com.mes.edgstoragecage.entity.EdgStorageCage;
import com.mes.edgstoragecage.entity.EdgStorageCageDetails;
import com.mes.edgstoragecage.service.EdgStorageCageDetailsService;
import com.mes.edgstoragecage.service.EdgStorageCageService;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.opctask.entity.EdgStorageDeviceTask;
import com.mes.opctask.entity.EdgStorageDeviceTaskHistory;
import com.mes.opctask.service.EdgStorageDeviceTaskHistoryService;
import com.mes.opctask.service.EdgStorageDeviceTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
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.List;
 
/**
 * @Author : zhoush
 * @Date: 2024/10/10 8:05
 * @Description:
 */
@Component
@Slf4j
public class OpcCacheGlassTask {
 
    @Autowired(required = false)
    MiloService miloService;
    @Resource
    EdgStorageDeviceTaskService edgStorageDeviceTaskService;
    @Resource
    GlassInfoService glassInfoService;
    @Resource
    EdgStorageCageDetailsService edgStorageCageDetailsService;
    @Resource
    EdgStorageCageService edgStorageCageService;
    @Resource
    EdgStorageDeviceTaskHistoryService edgStorageDeviceTaskHistoryService;
 
    @Value("${mes.glassGap}")
    private int glassGap;
    @Value("${mes.cellLength}")
    private int cellLength;
 
    @Value("${mes.threshold}")
    private int threshold;
//    @Autowired
//    MPJBaseService edgStorageDeviceTaskService;
//
//    @Autowired
//    SubscriptionCallback cacheGlassSubscriptionCallback;
//
//    @Scheduled(fixedDelay = Long.MAX_VALUE)
//    public void startOpcTask() throws Exception {
//        miloService.subscriptionFromOpcUa(Arrays.asList("my.device.x1", "my.device.x2"), cacheGlassSubscriptionCallback);
//    }
 
    @Scheduled(fixedDelay = 1000)
    public void startOpcTask() throws Exception {
        int request = 1;
//        获取笼内玻璃信息
        taskByDevice();
    }
 
    @Scheduled(fixedDelay = 1000)
    public void finishOpcTask() throws Exception {
        EdgStorageDeviceTask task = edgStorageDeviceTaskService.queryTaskMessage("edg_storage_device_one_task");
        if (task == null) {
            log.info("任务表基础数据录入失败,请检查数据是否录入成功");
            return;
        }
        if (task.getTaskState() <= 3) {
            log.info("不存在未完成的任务");
            return;
        }
        Integer cell = task.getStartCell();
        Integer state = task.getTaskState();
        task.setTaskRunning(Const.GLASS_CACHE_TYPE_EMPTY);
        task.setTaskState(Const.GLASS_CACHE_TYPE_EMPTY);
        task.setStartCell(-1);
        edgStorageDeviceTaskService.updateTaskMessage("edg_storage_device_one_task", task);
        edgStorageDeviceTaskHistoryService.update(new LambdaUpdateWrapper<EdgStorageDeviceTaskHistory>()
                .eq(EdgStorageDeviceTaskHistory::getTaskState, Const.RAW_GLASS_TASK_NEW)
                .set(EdgStorageDeviceTaskHistory::getTaskState,
                        Const.GLASS_CACHE_TYPE_RUNNING.equals(state) ? Const.RAW_GLASS_TASK_SUCCESS : Const.RAW_GLASS_TASK_FAILURE)
        );
        updateCellRemainWidth(cell);
    }
 
    private void taskByDevice() throws Exception {
        EdgStorageDeviceTask task = edgStorageDeviceTaskService.queryTaskMessage("edg_storage_device_one_task");
        if (task == null) {
            log.info("任务表基础数据录入失败,请检查数据是否录入成功");
            return;
        }
        int request = task.getTaskState();
        if (request == 0) {
            log.info("未收到任务请求,结束本次任务");
        } else if (request == 1) {
            //进片任务
            intoTask(task);
        } else if (request == 2) {
            //出片任务
            outTask(task);
        } else if (request == 3) {
            //todo:直通任务
 
        } else {
            log.info("异常数据,结束本次任务");
        }
    }
 
    private boolean intoTask(EdgStorageDeviceTask task) {
        //获取玻璃的基本信息
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, task.getGlassIdIn()));
        if (null == glassInfo) {
            log.info("进片玻璃信息不存在,玻璃id:{}", task.getGlassIdIn());
            return Boolean.FALSE;
        }
        //获取当前进片玻璃id和进片格子  相同尺寸可以放下的格子
//        select * from edg_storage_cage t left join edg_storage_cage_details t1 on t.slot = t1.slot
//        where t.device_id =1 and t1.state = 100 and t.remain_width >= 827 and t1.width = 827 and t1.height = 1124 order by abs(t.slot - 10)
        EdgStorageCage edgStorageCage = edgStorageCageService.getEdgStorageCageBySize(1, glassInfo.getWidth(), glassInfo.getHeight(), task.getCurrentCell());
        if (edgStorageCage == null) {
            log.info("相同尺寸可以放下的格子未找到,格子id:{}", task.getCurrentCell());
//            SELECT * from edg_storage_cage where device_id = 1 and remain_width > 1000 order by abs(slot - 10)
            List<EdgStorageCage> storageCageList = edgStorageCageService.list(new LambdaQueryWrapper<EdgStorageCage>().eq(EdgStorageCage::getDeviceId, 1)
                    .eq(EdgStorageCage::getEnableState, Const.SLOT_ON)
                    .ge(EdgStorageCage::getRemainWidth, glassInfo.getWidth()).last("order by abs(slot - " + task.getCurrentCell() + ")"));
//            //直通任务
//            if (flag && CollectionUtil.isNotEmpty(emptyList)) {
//                return emptyList.get(0);
//            }
            if (CollectionUtil.isEmpty(storageCageList) || storageCageList.size() == 1) {
                log.info("没有多余的空格子");
                return Boolean.FALSE;
            }
            edgStorageCage = storageCageList.get(0);
        }
        log.info("4、将玻璃信息插入卧式理片笼,当前玻璃信息:{}", glassInfo);
        EdgStorageCageDetails details = new EdgStorageCageDetails();
        BeanUtils.copyProperties(glassInfo, details);
        details.setState(Const.GLASS_STATE_IN);
        details.setSlot(edgStorageCage.getSlot());
        details.setDeviceId(edgStorageCage.getDeviceId());
        edgStorageCageDetailsService.save(details);
 
        //更新任务信息
        task.setStartCell(edgStorageCage.getSlot());
        task.setTaskRunning(task.getTaskState());
        edgStorageDeviceTaskService.updateTaskMessage("edg_storage_device_one_task", task);
        saveHistoryTask(task);
        return Boolean.TRUE;
    }
 
    private boolean outTask(EdgStorageDeviceTask task) {
        EdgStorageCageDetails edgStorageCageDetails = null;
        //笼内是版图相差是否超过阈值
        boolean flag = queryMaxMinDiff(threshold);
        if (flag) {
            EdgStorageCageDetails minEdgDetails = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                    .inSql(EdgStorageCageDetails::getSlot, "select slot from edg_storage_cage where enable_state = " + Const.SLOT_ON)
                    .eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN)
                    .orderByAsc(EdgStorageCageDetails::getTemperingLayoutId)
                    .orderBy(Boolean.TRUE, Boolean.TRUE, EdgStorageCageDetails::getTemperingFeedSequence)
                    .last("limit 1"));
//            select * from edg_storage_cage_details where width = 551 and height = 1151 and id in (select min(id ) from edg_storage_cage_details where state = 100 group by slot )
            edgStorageCageDetails = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                    .eq(EdgStorageCageDetails::getWidth, minEdgDetails.getWidth())
                    .eq(EdgStorageCageDetails::getHeight, minEdgDetails.getHeight())
                    .inSql(EdgStorageCageDetails::getId, "select min(id ) from edg_storage_cage_details where state = 100 group by slot ")
                    .last("order by abs(t.slot - " + task.getCurrentCell() + ")  asc limit 1")
            );
            if (null == edgStorageCageDetails) {
                edgStorageCageDetails = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                        .eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN)
                        .eq(EdgStorageCageDetails::getSlot, minEdgDetails.getSlot())
                        .orderByAsc(EdgStorageCageDetails::getId)
                        .last("limit 1")
                );
            }
        }
        if (null == edgStorageCageDetails) {
            //        获取上次任务
//        获取历史表中上次任务最后一片尺寸
            EdgStorageDeviceTaskHistory edgeData = edgStorageDeviceTaskHistoryService.getOne(new LambdaQueryWrapper<EdgStorageDeviceTaskHistory>()
                    .eq(EdgStorageDeviceTaskHistory::getTaskState, Const.RAW_GLASS_TASK_SUCCESS).
                            orderByDesc(EdgStorageDeviceTaskHistory::getId).last("limit 1"));
            GlassInfo one = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, edgeData.getGlassIdOut()));
            //笼内的玻璃的尺寸是否和上一次任务一致
            edgStorageCageDetails = edgStorageCageDetailsService.queryEdgStorageDetailsBySize(one.getWidth(), one.getHeight());
        }
        if (null == edgStorageCageDetails) {
            edgStorageCageDetails = edgStorageCageDetailsService.queryEdgStorageDetailsBySize(0, 0);
        }
        if (edgStorageCageDetails == null) {
            //和上次任务不存在相同尺寸
            log.info("笼内没有玻璃了");
            return Boolean.FALSE;
        }
        //玻璃信息替换
        String glassIdChange = queryAndChangeGlass(edgStorageCageDetails.getGlassId());
        //处理在卧理内的玻璃信息:笼内的数据处理
        queryEdgAndChangeGlass(edgStorageCageDetails.getGlassId(), glassIdChange);
        //生成出片任务
        task.setGlassIdOut(edgStorageCageDetails.getGlassId());
        task.setCurrentCell(edgStorageCageDetails.getSlot());
        task.setTaskRunning(Const.GLASS_CACHE_TYPE_OUT);
        edgStorageDeviceTaskService.updateTaskMessage("edg_storage_device_one_task", task);
        saveHistoryTask(task);
        //更新详情表任务出片中
        edgStorageCageDetailsService.update(new LambdaUpdateWrapper<EdgStorageCageDetails>()
                .set(EdgStorageCageDetails::getState, Const.GLASS_STATE_OUT)
                .eq(EdgStorageCageDetails::getGlassId, edgStorageCageDetails.getGlassId()));
        return Boolean.TRUE;
    }
 
    private boolean updateCellRemainWidth(int slot) {
        List<EdgStorageCageDetails> list = edgStorageCageDetailsService.list(new LambdaQueryWrapper<EdgStorageCageDetails>().eq(EdgStorageCageDetails::getSlot, slot)
                .eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN));
        if (CollectionUtil.isEmpty(list)) {
            log.info("格子{}内无玻璃,无法更新", slot);
            return Boolean.FALSE;
        }
        int widthTotal = (int) list.stream().map(e -> e.getWidth() + glassGap).mapToDouble(Double::intValue).sum();
        int remainWidth = cellLength - widthTotal >= 0 ? cellLength - widthTotal : 0;
        edgStorageCageService.update(new LambdaUpdateWrapper<EdgStorageCage>().
                set(EdgStorageCage::getRemainWidth, remainWidth).eq(EdgStorageCage::getSlot, slot));
        return Boolean.FALSE;
    }
 
 
    /**
     * 查询玻璃并进行交换
     *
     * @param glassId
     * @return
     */
    public String queryAndChangeGlass(String glassId) {
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
//                .inSql(GlassInfo::getEngineerId, "select engineer_id from engineering where state = 1"));
        Assert.isFalse(null == glassInfo, "玻璃信息不存在");        //按照玻璃尺寸
        LambdaQueryWrapper<GlassInfo> queryWrapper = new LambdaQueryWrapper<GlassInfo>()
                .eq(GlassInfo::getWidth, glassInfo.getWidth())
                .eq(GlassInfo::getHeight, glassInfo.getHeight())
                .eq(GlassInfo::getThickness, glassInfo.getThickness())
                .eq(GlassInfo::getFilmsid, glassInfo.getFilmsid())
                .eq(GlassInfo::getFlowCardId, glassInfo.getFlowCardId())
                .eq(GlassInfo::getTotalLayer, glassInfo.getTotalLayer())
                .eq(GlassInfo::getLayer, glassInfo.getLayer())
                .eq(GlassInfo::getEngineerId, glassInfo.getEngineerId())
                .notInSql(GlassInfo::getGlassId, "select distinct glass_id from edg_storage_cage_details " +
                        "where engineer_id = '" + glassInfo.getEngineerId() + "' and width = " + glassInfo.getWidth() + " and height = " + glassInfo.getHeight()
                        + " and state != 100")
                .orderByAsc(GlassInfo::getTemperingLayoutId)
                .orderBy(Boolean.TRUE, Boolean.TRUE, GlassInfo::getTemperingFeedSequence)
                .last("Limit 1");
        GlassInfo swapGlassInfo = glassInfoService.getOne(queryWrapper);
        if (swapGlassInfo != null && !glassInfo.getGlassId().equals(swapGlassInfo.getGlassId())) {
            String swapGlassId = swapGlassInfo.getGlassId();
            log.info("将玻璃{}和玻璃{},信息互换,进玻璃 {}", glassInfo, swapGlassInfo, swapGlassInfo);
            swapGlassInfo.setGlassId(glassId);
            glassInfo.setGlassId(swapGlassId);
            glassInfoService.updateById(swapGlassInfo);
            glassInfoService.updateById(glassInfo);
            return swapGlassId;
        }
        return "";
    }
 
 
    /**
     * 查询卧式理片玻璃并进行交换
     *
     * @param glassId
     * @return
     */
    public void queryEdgAndChangeGlass(String glassId, String swapGlassId) {
        if (StringUtils.isBlank(swapGlassId)) {
            log.info("当前出笼玻璃不存在需要替换的玻璃");
            return;
        }
        //获取待出笼的玻璃
        EdgStorageCageDetails glassInfo = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                .eq(EdgStorageCageDetails::getGlassId, glassId).eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN));
//        获取待出笼的玻璃需要替换的玻璃信息
        EdgStorageCageDetails swapGlassDetailInfo = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                .eq(EdgStorageCageDetails::getGlassId, swapGlassId).eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN));
 
//      玻璃小片表中玻璃已经替换,更新卧理笼内现有的准备出笼的玻璃信息,
        if (null == swapGlassDetailInfo) {
            GlassInfo glassInfoBase = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
                    .eq(GlassInfo::getGlassId, glassId));
            //需要替换的玻璃为存进卧理,仅需更新当前需要出笼的玻璃信息即可
            edgStorageCageDetailsService.update(new LambdaUpdateWrapper<EdgStorageCageDetails>()
                    .eq(EdgStorageCageDetails::getGlassId, glassId)
                    .set(EdgStorageCageDetails::getTemperingLayoutId, glassInfoBase.getTemperingLayoutId())
                    .set(EdgStorageCageDetails::getTemperingFeedSequence, glassInfoBase.getTemperingFeedSequence()));
        } else {
            //需要替换的玻璃都在卧理内,按照玻璃id对调玻璃信息:对调玻璃id即可
            edgStorageCageDetailsService.update(new LambdaUpdateWrapper<EdgStorageCageDetails>()
                    .eq(EdgStorageCageDetails::getId, glassInfo.getId())
                    .set(EdgStorageCageDetails::getTemperingLayoutId, swapGlassDetailInfo.getTemperingLayoutId())
                    .set(EdgStorageCageDetails::getTemperingFeedSequence, swapGlassDetailInfo.getTemperingFeedSequence())
            );
            edgStorageCageDetailsService.update(new LambdaUpdateWrapper<EdgStorageCageDetails>()
                    .eq(EdgStorageCageDetails::getId, swapGlassDetailInfo.getId())
                    .set(EdgStorageCageDetails::getTemperingLayoutId, glassInfo.getTemperingLayoutId())
                    .set(EdgStorageCageDetails::getTemperingFeedSequence, glassInfo.getTemperingFeedSequence())
            );
        }
    }
 
    /**
     * 获取详情表内最大最小版图id的差值,判断是否出最小版图玻璃
     *
     * @return
     */
    public boolean queryMaxMinDiff(int threshold) {
        //获取笼子内最大版图id和最小版图id插值,判断是否大于阈值,大于阈值直接出最小版图玻璃
        QueryWrapper<EdgStorageCageDetails> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("max(tempering_layout_id)-min(tempering_layout_id) as diff")
                .eq("state", Const.GLASS_STATE_IN)
                .inSql("slot", "select slot from edg_storage_cage where enable_state = " + Const.SLOT_ON);
        List<Object> list = edgStorageCageDetailsService.listObjs(queryWrapper);
        //获取笼内玻璃版图差值是否大于阈值
        if (CollectionUtil.isNotEmpty(list)) {
            Long diff = (Long) list.get(0);
            return diff > threshold;
        } else {
            return Boolean.FALSE;
        }
    }
 
    public boolean saveHistoryTask(EdgStorageDeviceTask task) {
        EdgStorageDeviceTaskHistory taskHistory = new EdgStorageDeviceTaskHistory();
        BeanUtils.copyProperties(task, taskHistory);
        task.setTaskType(task.getTaskRunning());
        task.setTaskState(Const.RAW_GLASS_TASK_NEW);
        edgStorageDeviceTaskHistoryService.save(taskHistory);
        return Boolean.TRUE;
    }
 
}