#
vincentlu
2025-03-17 15cbe9c08401f51e4ad739c48b2743993c966602
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
package com.zy.acs.manager.core.scheduler;
 
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.acs.common.utils.GsonUtils;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.manager.core.cache.CoreCache;
import com.zy.acs.manager.core.domain.BackpackDto;
import com.zy.acs.manager.core.domain.CodeStepDto;
import com.zy.acs.manager.core.domain.MapWsAgvVo;
import com.zy.acs.manager.core.domain.MapWsVo;
import com.zy.acs.manager.core.domain.type.JobType;
import com.zy.acs.manager.core.service.MapService;
import com.zy.acs.manager.manager.entity.Agv;
import com.zy.acs.manager.manager.entity.AgvDetail;
import com.zy.acs.manager.manager.entity.AgvModel;
import com.zy.acs.manager.manager.entity.Code;
import com.zy.acs.manager.manager.service.AgvDetailService;
import com.zy.acs.manager.manager.service.AgvModelService;
import com.zy.acs.manager.manager.service.AgvService;
import com.zy.acs.manager.manager.service.CodeService;
import com.zy.acs.manager.manager.websocket.MapWebSocket;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
 
@Slf4j
@Component
public class MapDataWsScheduler {
 
    public static final int WEBSOCKET_BROADCAST_INTERVAL = 300;
 
    private ExecutorService singleThreadExecutor;
 
    @Autowired
    private AgvService agvService;
    @Autowired
    private AgvDetailService agvDetailService;
    @Autowired
    private AgvModelService agvModelService;
    @Autowired
    private CodeService codeService;
    @Autowired
    private MapService mapService;
 
    @PostConstruct
    public void init() {
        this.singleThreadExecutor = Executors.newSingleThreadExecutor();
        this.singleThreadExecutor.execute(() -> {
            try { Thread.sleep(200); } catch (InterruptedException ignore) {}
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    MapWsVo mapWsVo = new MapWsVo();
                    mapWsVo.setAgvVos(syncAgv());
                    MapWebSocket.broadcast(GsonUtils.toJson(mapWsVo));
                    Thread.sleep(WEBSOCKET_BROADCAST_INTERVAL / 3);
                } catch (Exception e) {
                    log.error("MapDataWsScheduler.init", e);
                }
            }
        });
    }
 
    private List<MapWsAgvVo> syncAgv() {
        List<MapWsAgvVo> agvVos = new ArrayList<>();
 
        List<Agv> agvList = agvService.list(new LambdaQueryWrapper<Agv>()
//                .eq(Agv::getStatus, 1)
        );
 
        Map<String, List<String>> codeDataListMap = mapService.queryCodeListFromDynamicNode(null
                , agvList.stream().map(Agv::getUuid).collect(Collectors.toSet()));
 
        for (Agv agv : agvList) {
            AgvModel agvModel = agvModelService.getByAgvId(agv.getId());
            AgvDetail agvDetail = agvDetailService.selectByAgvId(agv.getId());
            if (null == agvDetail) { continue; }
            Long recentCode = agvDetail.getRecentCode();
            if (null == recentCode) { continue; }
            Code code = codeService.getCacheById(recentCode);
            if (null == code) { continue; }
 
            JobType jobType = this.getJobType(agv.getId(), code.getData());
 
            MapWsAgvVo vo = new MapWsAgvVo();
            vo.setAgvModel(agvModel.getType());
            vo.setAgvNo(agv.getUuid());
            vo.setCode(code.getData());
            vo.setDirection(agvDetail.getAgvAngle());
            vo.setBackpack(this.getBackpack(agv.getId(), agvDetail.getBackpack()));
            if (null != jobType && null != jobType.increase) {
                vo.setBackpack(vo.getBackpack() + (jobType.increase ? 1 : -1));
            }
            vo.setSlots(agvModel.getBackpack());
            vo.setBattery(agvDetail.getSoc());
            vo.setJobType(null == jobType ? null : jobType.breif);
            vo.setError(agvDetail.realError());
 
            vo.setDynamicRoute(codeDataListMap.get(agv.getUuid()));
 
            agvVos.add(vo);
        }
 
        return agvVos;
    }
 
    private JobType getJobType(Long agvId, String currCodeData) {
        if (null == agvId || Cools.isEmpty(currCodeData)) {
            return null;
        }
        CodeStepDto codeStepDto = CoreCache.AGV_MOCK_STEP_CACHE.get(agvId);
        if (null == codeStepDto) {
            return null;
        }
        if (!codeStepDto.getCodeData().equals(currCodeData)) {
            return null;
        }
        return codeStepDto.getJobType();
    }
 
    @PreDestroy
    public void destroy() {
        this.singleThreadExecutor.shutdownNow();
    }
 
    private Integer getBackpack(Long agvId, String backpackJson) {
        if (null == agvId || Cools.isEmpty(backpackJson)) {
            return 0;
        }
        List<BackpackDto> backpackDtoList = JSON.parseArray(backpackJson, BackpackDto.class);
        int jsonCount = (int) backpackDtoList.stream().filter(BackpackDto::getLoaded).count();
 
        Integer cacheCount = CoreCache.AGV_BACKPACK_USED_CACHE.get(agvId);
        if (null == cacheCount) {
            return jsonCount;
        }
        return Math.max(jsonCount, cacheCount);
    }
 
}