From c0760528d4c2c3411c8f9fff3d0e9db7ba9a658f Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期二, 03 三月 2026 16:47:06 +0800
Subject: [PATCH] #
---
src/main/java/com/zy/core/thread/impl/ZyStationV4Thread.java | 436 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 436 insertions(+), 0 deletions(-)
diff --git a/src/main/java/com/zy/core/thread/impl/ZyStationV4Thread.java b/src/main/java/com/zy/core/thread/impl/ZyStationV4Thread.java
new file mode 100644
index 0000000..a573950
--- /dev/null
+++ b/src/main/java/com/zy/core/thread/impl/ZyStationV4Thread.java
@@ -0,0 +1,436 @@
+package com.zy.core.thread.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.core.common.Cools;
+import com.core.common.DateUtils;
+import com.core.common.SpringUtils;
+import com.zy.asrs.entity.BasDevp;
+import com.zy.asrs.entity.BasStationOpt;
+import com.zy.asrs.entity.DeviceConfig;
+import com.zy.asrs.entity.DeviceDataLog;
+import com.zy.asrs.service.BasDevpService;
+import com.zy.asrs.service.BasStationOptService;
+import com.zy.asrs.utils.Utils;
+import com.zy.common.model.NavigateNode;
+import com.zy.common.utils.NavigateUtils;
+import com.zy.common.utils.RedisUtil;
+import com.zy.core.cache.MessageQueue;
+import com.zy.core.cache.OutputQueue;
+import com.zy.core.cache.SlaveConnection;
+import com.zy.core.enums.RedisKeyType;
+import com.zy.core.enums.SlaveType;
+import com.zy.core.enums.StationCommandType;
+import com.zy.core.model.CommandResponse;
+import com.zy.core.model.Task;
+import com.zy.core.model.command.StationCommand;
+import com.zy.core.model.protocol.StationProtocol;
+import com.zy.core.network.DeviceConnectPool;
+import com.zy.core.network.ZyStationConnectDriver;
+import com.zy.core.network.entity.ZyStationStatusEntity;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.text.MessageFormat;
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Data
+@Slf4j
+public class ZyStationV4Thread implements Runnable, com.zy.core.thread.StationThread {
+
+ private List<StationProtocol> statusList = new ArrayList<>();
+ private DeviceConfig deviceConfig;
+ private RedisUtil redisUtil;
+ private ZyStationConnectDriver zyStationConnectDriver;
+ private int deviceLogCollectTime = 200;
+ private long deviceDataLogTime = System.currentTimeMillis();
+ private ExecutorService executor = Executors.newFixedThreadPool(9999);
+
+ public ZyStationV4Thread(DeviceConfig deviceConfig, RedisUtil redisUtil) {
+ this.deviceConfig = deviceConfig;
+ this.redisUtil = redisUtil;
+ }
+
+ @Override
+ @SuppressWarnings("InfiniteLoopStatement")
+ public void run() {
+ this.connect();
+ deviceLogCollectTime = Utils.getDeviceLogCollectTime();
+
+ Thread readThread = new Thread(() -> {
+ while (true) {
+ try {
+ deviceLogCollectTime = Utils.getDeviceLogCollectTime();
+ readStatus();
+ Thread.sleep(100);
+ } catch (Exception e) {
+ log.error("StationV3Thread Fail", e);
+ }
+ }
+ });
+ readThread.start();
+
+ Thread processThread = new Thread(() -> {
+ while (true) {
+ try {
+ int step = 1;
+ Task task = MessageQueue.poll(SlaveType.Devp, deviceConfig.getDeviceNo());
+ if (task != null) {
+ step = task.getStep();
+ }
+ if (step == 2) {
+ StationCommand cmd = (StationCommand) task.getData();
+ executor.submit(() -> executeMoveWithSeg(cmd));
+ }
+ Thread.sleep(100);
+ } catch (Exception e) {
+ log.error("StationV3Process Fail", e);
+ }
+ }
+ });
+ processThread.start();
+ }
+
+ private void readStatus() {
+ if (zyStationConnectDriver == null) {
+ return;
+ }
+
+ if (statusList.isEmpty()) {
+ BasDevpService basDevpService = null;
+ try {
+ basDevpService = SpringUtils.getBean(BasDevpService.class);
+ } catch (Exception e) {
+ }
+ if (basDevpService == null) {
+ return;
+ }
+
+ BasDevp basDevp = basDevpService
+ .selectOne(new EntityWrapper<BasDevp>().eq("devp_no", deviceConfig.getDeviceNo()));
+ if (basDevp == null) {
+ return;
+ }
+
+ List<ZyStationStatusEntity> list = JSONObject.parseArray(basDevp.getStationList(), ZyStationStatusEntity.class);
+ for (ZyStationStatusEntity entity : list) {
+ StationProtocol stationProtocol = new StationProtocol();
+ stationProtocol.setStationId(entity.getStationId());
+ statusList.add(stationProtocol);
+ }
+ }
+
+ List<ZyStationStatusEntity> zyStationStatusEntities = zyStationConnectDriver.getStatus();
+ for (ZyStationStatusEntity statusEntity : zyStationStatusEntities) {
+ for (StationProtocol stationProtocol : statusList) {
+ if (stationProtocol.getStationId().equals(statusEntity.getStationId())) {
+ stationProtocol.setTaskNo(statusEntity.getTaskNo());
+ stationProtocol.setTargetStaNo(statusEntity.getTargetStaNo());
+ stationProtocol.setAutoing(statusEntity.isAutoing());
+ stationProtocol.setLoading(statusEntity.isLoading());
+ stationProtocol.setInEnable(statusEntity.isInEnable());
+ stationProtocol.setOutEnable(statusEntity.isOutEnable());
+ stationProtocol.setEmptyMk(statusEntity.isEmptyMk());
+ stationProtocol.setFullPlt(statusEntity.isFullPlt());
+ stationProtocol.setPalletHeight(statusEntity.getPalletHeight());
+ stationProtocol.setError(statusEntity.getError());
+ stationProtocol.setErrorMsg(statusEntity.getErrorMsg());
+ stationProtocol.setBarcode(statusEntity.getBarcode());
+ stationProtocol.setRunBlock(statusEntity.isRunBlock());
+ stationProtocol.setEnableIn(statusEntity.isEnableIn());
+ stationProtocol.setWeight(statusEntity.getWeight());
+ }
+
+ if (!Cools.isEmpty(stationProtocol.getSystemWarning())) {
+ if (stationProtocol.isAutoing()
+ && !stationProtocol.isLoading()
+ ) {
+ stationProtocol.setSystemWarning("");
+ }
+ }
+ }
+ }
+
+ OutputQueue.DEVP.offer(MessageFormat.format("銆恵0}銆慬id:{1}] <<<<< 瀹炴椂鏁版嵁鏇存柊鎴愬姛", DateUtils.convert(new Date()), deviceConfig.getDeviceNo()));
+
+ if (System.currentTimeMillis() - deviceDataLogTime > deviceLogCollectTime) {
+ DeviceDataLog deviceDataLog = new DeviceDataLog();
+ deviceDataLog.setOriginData(JSON.toJSONString(zyStationStatusEntities));
+ deviceDataLog.setWcsData(JSON.toJSONString(statusList));
+ deviceDataLog.setType(String.valueOf(SlaveType.Devp));
+ deviceDataLog.setDeviceNo(deviceConfig.getDeviceNo());
+ deviceDataLog.setCreateTime(new Date());
+
+ redisUtil.set(RedisKeyType.DEVICE_LOG_KEY.key + System.currentTimeMillis(), deviceDataLog, 60 * 60 * 24);
+ deviceDataLogTime = System.currentTimeMillis();
+ }
+ }
+
+ @Override
+ public boolean connect() {
+ zyStationConnectDriver = new ZyStationConnectDriver(deviceConfig, redisUtil);
+ zyStationConnectDriver.start();
+ DeviceConnectPool.put(SlaveType.Devp, deviceConfig.getDeviceNo(), zyStationConnectDriver);
+ return true;
+ }
+
+ @Override
+ public void close() {
+ if (zyStationConnectDriver != null) {
+ zyStationConnectDriver.close();
+ }
+ if (executor != null) {
+ try { executor.shutdownNow(); } catch (Exception ignore) {}
+ }
+ }
+
+ @Override
+ public List<StationProtocol> getStatus() {
+ return statusList;
+ }
+
+ @Override
+ public Map<Integer, StationProtocol> getStatusMap() {
+ Map<Integer, StationProtocol> map = new HashMap<>();
+ for (StationProtocol stationProtocol : statusList) {
+ map.put(stationProtocol.getStationId(), stationProtocol);
+ }
+ return map;
+ }
+
+ @Override
+ public StationCommand getCommand(StationCommandType commandType, Integer taskNo, Integer stationId, Integer targetStationId, Integer palletSize) {
+ StationCommand stationCommand = new StationCommand();
+ stationCommand.setTaskNo(taskNo);
+ stationCommand.setStationId(stationId);
+ stationCommand.setTargetStaNo(targetStationId);
+ stationCommand.setPalletSize(palletSize);
+ stationCommand.setCommandType(commandType);
+
+ if (commandType == StationCommandType.MOVE) {
+ if (!stationId.equals(targetStationId)) {
+ List<Integer> path = calcPathStationIds(stationId, targetStationId);
+ stationCommand.setNavigatePath(path);
+ }
+ }
+ return stationCommand;
+ }
+
+ @Override
+ public CommandResponse sendCommand(StationCommand command) {
+ CommandResponse commandResponse = null;
+ try {
+ commandResponse = zyStationConnectDriver.sendCommand(command);
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ BasStationOptService optService = SpringUtils.getBean(BasStationOptService.class);
+ List<ZyStationStatusEntity> statusListEntity = zyStationConnectDriver.getStatus();
+ ZyStationStatusEntity matched = null;
+ if (statusListEntity != null) {
+ for (ZyStationStatusEntity e : statusListEntity) {
+ if (e.getStationId() != null && e.getStationId().equals(command.getStationId())) {
+ matched = e;
+ break;
+ }
+ }
+ }
+ BasStationOpt basStationOpt = new BasStationOpt(
+ command.getTaskNo(),
+ command.getStationId(),
+ new Date(),
+ String.valueOf(command.getCommandType()),
+ command.getStationId(),
+ command.getTargetStaNo(),
+ null,
+ null,
+ null,
+ JSON.toJSONString(command),
+ JSON.toJSONString(matched),
+ 1,
+ JSON.toJSONString(commandResponse)
+ );
+ if (optService != null) {
+ optService.insert(basStationOpt);
+ }
+ }
+ return commandResponse;
+ }
+
+ @Override
+ public CommandResponse sendOriginCommand(String address, short[] data) {
+ return zyStationConnectDriver.sendOriginCommand(address, data);
+ }
+
+ @Override
+ public byte[] readOriginCommand(String address, int length) {
+ return zyStationConnectDriver.readOriginCommand(address, length);
+ }
+
+ private List<Integer> calcPathStationIds(Integer startStationId, Integer targetStationId) {
+ NavigateUtils navigateUtils = SpringUtils.getBean(NavigateUtils.class);
+ if (navigateUtils == null) {
+ return new ArrayList<>();
+ }
+ List<NavigateNode> nodes = navigateUtils.calcByStationId(startStationId, targetStationId);
+ List<Integer> ids = new ArrayList<>();
+ for (NavigateNode n : nodes) {
+ JSONObject v = JSONObject.parseObject(n.getNodeValue());
+ if (v != null) {
+ ids.add(v.getInteger("stationId"));
+ }
+ }
+ return ids;
+ }
+
+ private void executeMoveWithSeg(StationCommand original) {
+ int stationCommandSendLength = 20;
+ Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
+ if (systemConfigMapObj != null) {
+ try {
+ HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
+ String stationCommandSendLengthStr = systemConfigMap.get("stationCommandSendLength");
+ if(stationCommandSendLengthStr != null){
+ stationCommandSendLength = Integer.parseInt(stationCommandSendLengthStr);
+ }
+ } catch (Exception ignore) {}
+ }
+
+ if(original.getCommandType() == StationCommandType.MOVE){
+ List<Integer> path = JSON.parseArray(JSON.toJSONString(original.getNavigatePath(), SerializerFeature.DisableCircularReferenceDetect), Integer.class);
+ if (path == null || path.isEmpty()) {
+ return;
+ }
+
+ int total = path.size();
+ List<Integer> segmentTargets = new ArrayList<>();
+ List<Integer> segmentEndIndices = new ArrayList<>();
+ int idx = 0;
+ while (idx < total) {
+ int end = Math.min(idx + stationCommandSendLength, total) - 1;
+ segmentTargets.add(path.get(end));
+ segmentEndIndices.add(end);
+ idx = end + 1;
+ }
+
+ int segCursor = 0;
+ Integer currentTarget = segmentTargets.get(segCursor);
+ Integer currentEndIdx = segmentEndIndices.get(segCursor);
+ Integer currentStartIdx = 0;
+
+ StationCommand segCmd = new StationCommand();
+ segCmd.setTaskNo(original.getTaskNo());
+ segCmd.setStationId(original.getStationId());
+ segCmd.setTargetStaNo(original.getTargetStaNo());
+ segCmd.setCommandType(original.getCommandType());
+ segCmd.setPalletSize(original.getPalletSize());
+ segCmd.setNavigatePath(new ArrayList<>(path.subList(0, currentEndIdx + 1)));
+ sendCommand(segCmd);
+
+ long runTime = System.currentTimeMillis();
+ boolean firstRun = true;
+ while (true) {
+ try {
+ Object cancel = redisUtil.get(RedisKeyType.DEVICE_STATION_MOVE_RESET.key + original.getTaskNo());
+ if (cancel != null) {
+ break;//鏀跺埌涓柇淇″彿
+ }
+
+ StationProtocol currentStation = findCurrentStationByTask(original.getTaskNo());
+ if (currentStation == null) {
+ if(System.currentTimeMillis() - runTime > 1000 * 60){
+ break;
+ }
+ Thread.sleep(500);
+ continue;
+ }
+
+ runTime = System.currentTimeMillis();
+ if (!firstRun && currentStation.isRunBlock()) {
+ break;
+ }
+ int currentIndex = path.indexOf(currentStation.getStationId());
+ if (currentIndex < 0) {
+ Thread.sleep(500);
+ continue;
+ }
+ int remaining = total - currentIndex - 1;
+ if (remaining <= 0) {
+ break;
+ }
+ int currentSegEndIndex = path.indexOf(segmentTargets.get(segCursor));
+ int currentSegStartIndex = segCursor == 0 ? 0 : path.indexOf(segmentTargets.get(segCursor - 1)) + 1;
+ int segLen = currentSegEndIndex - currentSegStartIndex + 1;
+ int remainingSegment = Math.max(0, currentSegEndIndex - currentIndex);
+ int thresholdSegment = (int) Math.ceil(segLen * 0.3);
+ if (remainingSegment <= thresholdSegment && segCursor < segmentTargets.size() - 1) {
+ segCursor++;
+ currentEndIdx = segmentEndIndices.get(segCursor);
+ currentStartIdx = segmentEndIndices.get(segCursor - 1) + 1;
+
+ StationCommand nextCmd = new StationCommand();
+ nextCmd.setTaskNo(original.getTaskNo());
+ nextCmd.setStationId(original.getStationId());
+ nextCmd.setTargetStaNo(original.getTargetStaNo());
+ nextCmd.setCommandType(original.getCommandType());
+ nextCmd.setPalletSize(original.getPalletSize());
+ nextCmd.setNavigatePath(new ArrayList<>(path.subList(currentStartIdx, currentEndIdx + 1)));
+ nextCmd.setOriginalNavigatePath(path);
+ while (true) {
+ CommandResponse commandResponse = sendCommand(nextCmd);
+ if (commandResponse == null) {
+ Thread.sleep(200);
+ continue;
+ }
+
+ if (commandResponse.getResult()) {
+ break;
+ }
+
+ Thread.sleep(200);
+ }
+ }
+ Thread.sleep(500);
+ } catch (Exception e) {
+ break;
+ }
+ firstRun = false;
+ }
+ }else {
+ sendCommand(original);
+ }
+ }
+
+ private StationProtocol findCurrentStationByTask(Integer taskNo) {
+ try {
+ com.zy.asrs.service.DeviceConfigService deviceConfigService = SpringUtils.getBean(com.zy.asrs.service.DeviceConfigService.class);
+ if (deviceConfigService == null) {
+ return null;
+ }
+ List<DeviceConfig> devpList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+ .eq("device_type", String.valueOf(SlaveType.Devp)));
+ for (DeviceConfig dc : devpList) {
+ com.zy.core.thread.StationThread t = (com.zy.core.thread.StationThread) SlaveConnection.get(SlaveType.Devp, dc.getDeviceNo());
+ if (t == null) {
+ continue;
+ }
+ Map<Integer, StationProtocol> m = t.getStatusMap();
+ if (m == null || m.isEmpty()) {
+ continue;
+ }
+ for (StationProtocol sp : m.values()) {
+ if (sp.getTaskNo() != null && sp.getTaskNo().equals(taskNo) && sp.isLoading()) {
+ return sp;
+ }
+ }
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ return null;
+ }
+}
--
Gitblit v1.9.1