package com.zy.core.network.fake;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONObject;
|
import com.zy.asrs.entity.DeviceConfig;
|
import com.zy.common.utils.RedisUtil;
|
import com.zy.core.News;
|
import com.zy.core.enums.RedisKeyType;
|
import com.zy.core.enums.StationCommandType;
|
import com.zy.core.model.CommandResponse;
|
import com.zy.core.model.command.StationCommand;
|
import com.zy.core.network.api.ZyStationConnectApi;
|
import com.zy.core.network.entity.ZyStationStatusEntity;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Random;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.Executors;
|
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.Map;
|
import java.util.Arrays;
|
|
public class ZyStationFakeSegConnect implements ZyStationConnectApi {
|
|
// 站点级锁:每个站点独立一把锁,提升并发性能
|
private final Map<Integer, ReentrantLock> stationLocks = new ConcurrentHashMap<>();
|
private HashMap<Integer, List<ZyStationStatusEntity>> deviceStatusMap = new HashMap<>();
|
private HashMap<Integer, DeviceConfig> deviceConfigMap = new HashMap<>();
|
private RedisUtil redisUtil;
|
private final Map<Integer, BlockingQueue<StationCommand>> taskQueues = new ConcurrentHashMap<>();
|
private final Map<Integer, Long> taskLastUpdateTime = new ConcurrentHashMap<>();
|
private final Map<Integer, Boolean> taskRunning = new ConcurrentHashMap<>();
|
private final ExecutorService executor = Executors.newCachedThreadPool();
|
|
public void addFakeConnect(DeviceConfig deviceConfig, RedisUtil redisUtil) {
|
this.redisUtil = redisUtil;
|
|
if (deviceConfigMap.containsKey(deviceConfig.getDeviceNo())) {
|
return;
|
}
|
deviceConfigMap.put(deviceConfig.getDeviceNo(), deviceConfig);
|
deviceStatusMap.put(deviceConfig.getDeviceNo(), new CopyOnWriteArrayList<>());
|
}
|
|
@Override
|
public boolean connect() {
|
Thread checkThread = new Thread(() -> {
|
while (true) {
|
try {
|
for (Map.Entry<Integer, List<ZyStationStatusEntity>> entry : deviceStatusMap.entrySet()) {
|
List<ZyStationStatusEntity> stationList = entry.getValue();
|
for (ZyStationStatusEntity statusEntity : stationList) {
|
if (statusEntity.isAutoing()
|
&& statusEntity.isLoading()
|
&& statusEntity.getTaskNo() > 0
|
&& !statusEntity.isRunBlock()
|
&& !statusEntity.getStationId().equals(statusEntity.getTargetStaNo())) {
|
BlockingQueue<StationCommand> commands = taskQueues.get(statusEntity.getTaskNo());
|
if (commands == null) {
|
statusEntity.setRunBlock(true);
|
}
|
}
|
}
|
}
|
|
Thread.sleep(100);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
});
|
// checkThread.start();
|
return true;
|
}
|
|
@Override
|
public boolean disconnect() {
|
executor.shutdownNow();
|
return true;
|
}
|
|
@Override
|
public List<ZyStationStatusEntity> getStatus(Integer deviceNo) {
|
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo);
|
if (statusList == null) {
|
return new ArrayList<>();
|
}
|
DeviceConfig deviceConfig = deviceConfigMap.get(deviceNo);
|
if (statusList.isEmpty()) {
|
List<ZyStationStatusEntity> init = JSON.parseArray(deviceConfig.getFakeInitStatus(),
|
ZyStationStatusEntity.class);
|
if (init != null) {
|
statusList.addAll(init);
|
for (ZyStationStatusEntity status : statusList) {
|
status.setAutoing(true);
|
status.setLoading(false);
|
status.setInEnable(true);
|
status.setOutEnable(true);
|
status.setEmptyMk(false);
|
status.setFullPlt(false);
|
status.setRunBlock(false);
|
status.setPalletHeight(0);
|
status.setError(0);
|
status.setBarcode("");
|
}
|
}
|
}
|
|
return statusList;
|
}
|
|
@Override
|
public CommandResponse sendCommand(Integer deviceNo, StationCommand command) {
|
Integer taskNo = command.getTaskNo();
|
if (taskNo == null) {
|
return new CommandResponse(false, "任务号为空");
|
}
|
|
// 处理非移动命令
|
if (command.getCommandType() != StationCommandType.MOVE) {
|
handleCommand(deviceNo, command);
|
} else {
|
// 将移动命令追加到任务队列(支持分段下发)
|
taskQueues.computeIfAbsent(taskNo, k -> new LinkedBlockingQueue<>()).offer(command);
|
taskLastUpdateTime.put(taskNo, System.currentTimeMillis());
|
|
// 只有任务未启动时才启动执行器,后续分段命令仅追加到队列
|
if (taskRunning.putIfAbsent(taskNo, true) == null) {
|
executor.submit(() -> runTaskLoop(deviceNo, taskNo));
|
}
|
// 后续分段命令不再返回错误,正常追加到队列
|
}
|
|
return new CommandResponse(true, "命令已受理(异步执行)");
|
}
|
|
private void runTaskLoop(Integer deviceNo, Integer taskNo) {
|
try {
|
// 待执行的路径队列(存储站点ID序列)
|
LinkedBlockingQueue<Integer> pendingPathQueue = new LinkedBlockingQueue<>();
|
// 当前所在站点ID
|
Integer currentStationId = null;
|
// 最终目标站点ID
|
Integer finalTargetStationId = null;
|
// 是否需要生成条码
|
boolean generateBarcode = false;
|
// 是否已初始化起点
|
boolean initialized = false;
|
// 上一步执行时间(用于堵塞检测)
|
long stepExecuteTime = System.currentTimeMillis();
|
|
while (true) {
|
if (Thread.currentThread().isInterrupted()) {
|
break;
|
}
|
|
BlockingQueue<StationCommand> commandQueue = taskQueues.get(taskNo);
|
if (commandQueue == null) {
|
break;
|
}
|
|
// 尝试获取新的分段命令
|
StationCommand command = commandQueue.poll(100, TimeUnit.MILLISECONDS);
|
if (command != null) {
|
taskLastUpdateTime.put(taskNo, System.currentTimeMillis());
|
|
// 首次接收命令时初始化
|
if (finalTargetStationId == null) {
|
finalTargetStationId = command.getTargetStaNo();
|
if (checkTaskNoInArea(taskNo)) {
|
generateBarcode = true;
|
}
|
}
|
|
// 将新路径追加到待执行队列
|
List<Integer> newPath = command.getNavigatePath();
|
if (newPath != null && !newPath.isEmpty()) {
|
// 获取队列中最后一个站点(用于衔接点去重)
|
Integer lastInQueue = getLastInQueue(pendingPathQueue);
|
if (lastInQueue == null) {
|
lastInQueue = currentStationId;
|
}
|
|
int startIndex = 0;
|
// 如果新路径的起点与当前位置或队列末尾重复,则跳过
|
if (lastInQueue != null && !newPath.isEmpty() && newPath.get(0).equals(lastInQueue)) {
|
startIndex = 1;
|
}
|
|
for (int i = startIndex; i < newPath.size(); i++) {
|
pendingPathQueue.offer(newPath.get(i));
|
}
|
|
News.info("[WCS Debug] 任务{}追加路径段: {} -> 队列大小: {}", taskNo, newPath, pendingPathQueue.size());
|
}
|
}
|
|
// 执行移动逻辑
|
if (!pendingPathQueue.isEmpty()) {
|
Integer nextStationId = pendingPathQueue.peek();
|
|
// 如果尚未初始化起点
|
if (!initialized && currentStationId == null) {
|
// 优先查找托盘当前实际位置(支持堵塞后重路由场景)
|
Integer actualCurrentStationId = findCurrentStationIdByTask(taskNo);
|
if (actualCurrentStationId != null) {
|
// 找到了当前托盘位置,使用实际位置作为起点
|
currentStationId = actualCurrentStationId;
|
initialized = true;
|
|
// 清除该站点的 runBlock 标记(堵塞恢复)
|
Integer deviceId = getDeviceNoByStationId(currentStationId);
|
if (deviceId != null) {
|
clearRunBlock(currentStationId, deviceId);
|
}
|
|
// 如果路径起点与当前位置相同,移除起点避免重复
|
if (nextStationId.equals(currentStationId)) {
|
pendingPathQueue.poll();
|
}
|
|
stepExecuteTime = System.currentTimeMillis();
|
News.info("[WCS Debug] 任务{}恢复执行,当前位置: {}", taskNo, currentStationId);
|
continue;
|
}
|
|
// 未找到当前位置(首次执行),首个站点就是起点
|
currentStationId = nextStationId;
|
Integer deviceId = getDeviceNoByStationId(currentStationId);
|
if (deviceId != null) {
|
boolean result = initStationMove(taskNo, currentStationId, deviceId, taskNo,
|
finalTargetStationId, true, null);
|
if (result) {
|
initialized = true;
|
pendingPathQueue.poll(); // 移除起点
|
stepExecuteTime = System.currentTimeMillis();
|
News.info("[WCS Debug] 任务{}初始化起点: {}", taskNo, currentStationId);
|
}
|
}
|
sleep(500);
|
continue;
|
}
|
|
// 执行从当前站点到下一站点的移动
|
Integer currentDeviceNo = getDeviceNoByStationId(currentStationId);
|
Integer nextDeviceNo = getDeviceNoByStationId(nextStationId);
|
|
if (currentDeviceNo != null && nextDeviceNo != null) {
|
boolean moveSuccess = stationMoveToNext(taskNo, currentStationId, currentDeviceNo,
|
nextStationId, nextDeviceNo, taskNo, finalTargetStationId);
|
if (moveSuccess) {
|
currentStationId = nextStationId;
|
pendingPathQueue.poll();
|
stepExecuteTime = System.currentTimeMillis();
|
News.info("[WCS Debug] 任务{}移动到站点: {}, 剩余队列: {}", taskNo, currentStationId,
|
pendingPathQueue.size());
|
sleep(1000); // 模拟移动耗时
|
} else {
|
// 移动失败,检查是否堵塞
|
if (!checkTaskNoInArea(taskNo)) {
|
boolean fakeAllowCheckBlock = getFakeAllowCheckBlock();
|
|
if (fakeAllowCheckBlock && System.currentTimeMillis() - stepExecuteTime > 10000) {
|
// 认定堵塞
|
boolean result = runBlockStation(taskNo, currentStationId, currentDeviceNo, taskNo,
|
currentStationId);
|
if (result) {
|
News.info("[WCS Debug] 任务{}在站点{}被标记为堵塞", taskNo, currentStationId);
|
pendingPathQueue.clear();
|
break;
|
}
|
}
|
}
|
sleep(500); // 失败重试等待
|
}
|
} else {
|
// 无法获取设备号,跳过该站点
|
pendingPathQueue.poll();
|
}
|
} else {
|
// 路径队列为空,等待新的分段命令
|
if (currentStationId != null && finalTargetStationId != null
|
&& currentStationId.equals(finalTargetStationId)) {
|
// 已到达最终目标,正常结束
|
if (generateBarcode) {
|
Integer targetDeviceNo = getDeviceNoByStationId(finalTargetStationId);
|
if (targetDeviceNo != null) {
|
generateStationBarcode(taskNo, finalTargetStationId, targetDeviceNo);
|
News.info("[WCS Debug] 任务{}到达目标{}并生成条码", taskNo, finalTargetStationId);
|
}
|
}
|
break;
|
}
|
|
// 未到达最终目标,等待新的分段命令
|
Long lastTime = taskLastUpdateTime.get(taskNo);
|
if (lastTime != null && System.currentTimeMillis() - lastTime > 30000) {
|
// 超时:30秒内没有收到新分段命令
|
News.info("[WCS Debug] 任务{}等待分段超时,当前位置: {}, 目标: {}", taskNo, currentStationId,
|
finalTargetStationId);
|
break;
|
}
|
// 继续等待新分段命令(不做任何事情,下一轮循环会尝试获取新命令)
|
}
|
}
|
} catch (InterruptedException e) {
|
Thread.currentThread().interrupt();
|
} finally {
|
taskQueues.remove(taskNo);
|
taskLastUpdateTime.remove(taskNo);
|
taskRunning.remove(taskNo);
|
News.info("[WCS Debug] 任务{}执行结束并清理资源", taskNo);
|
}
|
}
|
|
/**
|
* 获取队列中最后一个元素(不移除)
|
*/
|
private Integer getLastInQueue(LinkedBlockingQueue<Integer> queue) {
|
Integer last = null;
|
for (Integer item : queue) {
|
last = item;
|
}
|
return last;
|
}
|
|
/**
|
* 获取是否允许检查堵塞的配置
|
*/
|
private boolean getFakeAllowCheckBlock() {
|
boolean fakeAllowCheckBlock = true;
|
Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
|
if (systemConfigMapObj != null) {
|
HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
|
String value = systemConfigMap.get("fakeAllowCheckBlock");
|
if (value != null && !value.equals("Y")) {
|
fakeAllowCheckBlock = false;
|
}
|
}
|
return fakeAllowCheckBlock;
|
}
|
|
@Override
|
public CommandResponse sendOriginCommand(String address, short[] data) {
|
return new CommandResponse(true, "原始命令已受理(异步执行)");
|
}
|
|
@Override
|
public byte[] readOriginCommand(String address, int length) {
|
return new byte[0];
|
}
|
|
private void handleCommand(Integer deviceNo, StationCommand command) {
|
News.info("[WCS Debug] 站点仿真模拟(V3)已启动,命令数据={}", JSON.toJSONString(command));
|
Integer taskNo = command.getTaskNo();
|
Integer stationId = command.getStationId();
|
Integer targetStationId = command.getTargetStaNo();
|
boolean generateBarcode = false;
|
|
if (command.getCommandType() == StationCommandType.RESET) {
|
resetStation(deviceNo, stationId);
|
return;
|
}
|
|
if (checkTaskNoInArea(taskNo)) {
|
generateBarcode = true;
|
}
|
|
if (command.getCommandType() == StationCommandType.WRITE_INFO) {
|
if (taskNo == 9998 && targetStationId == 0) {
|
// 生成出库站点仿真数据
|
generateFakeOutStationData(deviceNo, stationId);
|
return;
|
}
|
}
|
|
if (taskNo > 0 && taskNo != 9999 && taskNo != 9998 && stationId == targetStationId) {
|
generateStationData(deviceNo, taskNo, stationId, targetStationId);
|
}
|
// 注意:MOVE 类型的命令现已在 sendCommand 中处理,handleCommand 仅处理非 MOVE 命令
|
}
|
|
private void generateFakeOutStationData(Integer deviceNo, Integer stationId) {
|
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo);
|
ZyStationStatusEntity status = statusList.stream()
|
.filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null);
|
if (status == null) {
|
return;
|
}
|
|
synchronized (status) {
|
status.setLoading(true);
|
}
|
}
|
|
private void generateStationData(Integer deviceNo, Integer taskNo, Integer stationId, Integer targetStationId) {
|
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo);
|
ZyStationStatusEntity status = statusList.stream()
|
.filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null);
|
if (status == null) {
|
return;
|
}
|
|
synchronized (status) {
|
status.setTaskNo(taskNo);
|
status.setTargetStaNo(targetStationId);
|
}
|
}
|
|
private void resetStation(Integer deviceNo, Integer stationId) {
|
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo);
|
ZyStationStatusEntity status = statusList.stream()
|
.filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null);
|
if (status == null) {
|
return;
|
}
|
|
synchronized (status) {
|
status.setTaskNo(0);
|
status.setLoading(false);
|
status.setBarcode("");
|
}
|
}
|
|
// segmentedPathCommand 方法已删除,功能已整合到 runTaskLoop
|
|
private Integer getDeviceNoByStationId(Integer stationId) {
|
for (Integer devNo : deviceStatusMap.keySet()) {
|
List<ZyStationStatusEntity> list = deviceStatusMap.get(devNo);
|
if (list == null) {
|
continue;
|
}
|
for (ZyStationStatusEntity e : list) {
|
if (e.getStationId() != null && e.getStationId().equals(stationId)) {
|
return devNo;
|
}
|
}
|
}
|
return null;
|
}
|
|
private Integer findCurrentStationIdByTask(Integer taskNo) {
|
for (Integer devNo : deviceStatusMap.keySet()) {
|
List<ZyStationStatusEntity> list = deviceStatusMap.get(devNo);
|
if (list == null) {
|
continue;
|
}
|
for (ZyStationStatusEntity e : list) {
|
if (e.getTaskNo() != null && e.getTaskNo().equals(taskNo) && e.isLoading()) {
|
return e.getStationId();
|
}
|
}
|
}
|
return null;
|
}
|
|
// stationMoveByPathIds 方法已删除,功能已整合到 runTaskLoop
|
|
private void sleep(long ms) {
|
try {
|
Thread.sleep(ms);
|
} catch (InterruptedException e) {
|
Thread.currentThread().interrupt();
|
}
|
}
|
|
/**
|
* 获取站点锁,如果不存在则创建
|
*/
|
private ReentrantLock getStationLock(Integer stationId) {
|
return stationLocks.computeIfAbsent(stationId, k -> new ReentrantLock());
|
}
|
|
/**
|
* 按顺序锁定多个站点(避免死锁)
|
*/
|
private void lockStations(Integer... stationIds) {
|
Integer[] sorted = Arrays.copyOf(stationIds, stationIds.length);
|
Arrays.sort(sorted);
|
for (Integer stationId : sorted) {
|
getStationLock(stationId).lock();
|
}
|
}
|
|
/**
|
* 按逆序解锁多个站点
|
*/
|
private void unlockStations(Integer... stationIds) {
|
Integer[] sorted = Arrays.copyOf(stationIds, stationIds.length);
|
Arrays.sort(sorted);
|
for (int i = sorted.length - 1; i >= 0; i--) {
|
getStationLock(sorted[i]).unlock();
|
}
|
}
|
|
/**
|
* 更新站点数据(调用前必须已持有该站点的锁)
|
*/
|
private boolean updateStationDataInternal(Integer stationId, Integer deviceNo, Integer taskNo, Integer targetStaNo,
|
Boolean isLoading, String barcode, Boolean runBlock) {
|
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo);
|
if (statusList == null) {
|
return false;
|
}
|
|
ZyStationStatusEntity currentStatus = statusList.stream()
|
.filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null);
|
|
if (currentStatus == null) {
|
return false;
|
}
|
|
if (taskNo != null) {
|
currentStatus.setTaskNo(taskNo);
|
}
|
|
if (targetStaNo != null) {
|
currentStatus.setTargetStaNo(targetStaNo);
|
}
|
|
if (isLoading != null) {
|
currentStatus.setLoading(isLoading);
|
}
|
|
if (barcode != null) {
|
currentStatus.setBarcode(barcode);
|
}
|
|
if (runBlock != null) {
|
currentStatus.setRunBlock(runBlock);
|
}
|
return true;
|
}
|
|
/**
|
* 初始化站点移动(使用站点级锁)
|
*/
|
public boolean initStationMove(Integer lockTaskNo, Integer currentStationId, Integer currentStationDeviceNo,
|
Integer taskNo, Integer targetStationId, Boolean isLoading, String barcode) {
|
lockStations(currentStationId);
|
try {
|
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(currentStationDeviceNo);
|
if (statusList == null) {
|
return false;
|
}
|
|
ZyStationStatusEntity currentStatus = statusList.stream()
|
.filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null);
|
|
if (currentStatus == null) {
|
return false;
|
}
|
|
if (currentStatus.getTaskNo() > 0) {
|
if (!currentStatus.getTaskNo().equals(taskNo) && currentStatus.isLoading()) {
|
return false;
|
}
|
}
|
|
return updateStationDataInternal(currentStationId, currentStationDeviceNo, taskNo, targetStationId,
|
isLoading, barcode, false);
|
} finally {
|
unlockStations(currentStationId);
|
}
|
}
|
|
/**
|
* 站点移动到下一个位置(使用站点级锁,按ID顺序获取锁避免死锁)
|
*/
|
public boolean stationMoveToNext(Integer lockTaskNo, Integer currentStationId, Integer currentStationDeviceNo,
|
Integer nextStationId, Integer nextStationDeviceNo, Integer taskNo, Integer targetStaNo) {
|
// 同时锁定当前站点和下一个站点(按ID顺序,避免死锁)
|
lockStations(currentStationId, nextStationId);
|
try {
|
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(currentStationDeviceNo);
|
if (statusList == null) {
|
return false;
|
}
|
|
List<ZyStationStatusEntity> nextStatusList = deviceStatusMap.get(nextStationDeviceNo);
|
if (nextStatusList == null) {
|
return false;
|
}
|
|
ZyStationStatusEntity currentStatus = statusList.stream()
|
.filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null);
|
|
ZyStationStatusEntity nextStatus = nextStatusList.stream()
|
.filter(item -> item.getStationId().equals(nextStationId)).findFirst().orElse(null);
|
|
if (currentStatus == null || nextStatus == null) {
|
return false;
|
}
|
|
if (nextStatus.getTaskNo() > 0 || nextStatus.isLoading()) {
|
return false;
|
}
|
|
boolean result = updateStationDataInternal(nextStationId, nextStationDeviceNo, taskNo, targetStaNo, true,
|
null, false);
|
if (!result) {
|
return false;
|
}
|
|
boolean result2 = updateStationDataInternal(currentStationId, currentStationDeviceNo, 0, 0, false, "",
|
false);
|
if (!result2) {
|
return false;
|
}
|
|
return true;
|
} finally {
|
unlockStations(currentStationId, nextStationId);
|
}
|
}
|
|
/**
|
* 生成站点条码(使用站点级锁)
|
*/
|
public boolean generateStationBarcode(Integer lockTaskNo, Integer currentStationId,
|
Integer currentStationDeviceNo) {
|
lockStations(currentStationId);
|
try {
|
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(currentStationDeviceNo);
|
if (statusList == null) {
|
return false;
|
}
|
|
ZyStationStatusEntity currentStatus = statusList.stream()
|
.filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null);
|
|
if (currentStatus == null) {
|
return false;
|
}
|
|
Random random = new Random();
|
|
String barcodeTime = String.valueOf(System.currentTimeMillis());
|
String barcode = String.valueOf(random.nextInt(10)) + String.valueOf(random.nextInt(10))
|
+ barcodeTime.substring(7);
|
|
return updateStationDataInternal(currentStationId, currentStationDeviceNo, null, null, null, barcode, null);
|
} finally {
|
unlockStations(currentStationId);
|
}
|
}
|
|
/**
|
* 清除站点数据(使用站点级锁)
|
*/
|
public boolean clearStation(Integer deviceNo, Integer lockTaskNo, Integer currentStationId) {
|
lockStations(currentStationId);
|
try {
|
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo);
|
if (statusList == null) {
|
return false;
|
}
|
|
ZyStationStatusEntity currentStatus = statusList.stream()
|
.filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null);
|
|
if (currentStatus == null) {
|
return false;
|
}
|
|
return updateStationDataInternal(currentStationId, deviceNo, 0, 0, false, "", false);
|
} finally {
|
unlockStations(currentStationId);
|
}
|
}
|
|
/**
|
* 标记站点堵塞(使用站点级锁)
|
*/
|
public boolean runBlockStation(Integer lockTaskNo, Integer currentStationId, Integer currentStationDeviceNo,
|
Integer taskNo, Integer blockStationId) {
|
lockStations(currentStationId);
|
try {
|
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(currentStationDeviceNo);
|
if (statusList == null) {
|
return false;
|
}
|
|
ZyStationStatusEntity currentStatus = statusList.stream()
|
.filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null);
|
|
if (currentStatus == null) {
|
return false;
|
}
|
|
return updateStationDataInternal(currentStationId, currentStationDeviceNo, taskNo, blockStationId, true, "",
|
true);
|
} finally {
|
unlockStations(currentStationId);
|
}
|
}
|
|
/**
|
* 清除站点堵塞标记(堵塞恢复时使用)
|
*/
|
public void clearRunBlock(Integer stationId, Integer deviceNo) {
|
lockStations(stationId);
|
try {
|
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo);
|
if (statusList == null) {
|
return;
|
}
|
|
ZyStationStatusEntity currentStatus = statusList.stream()
|
.filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null);
|
|
if (currentStatus == null) {
|
return;
|
}
|
|
if (currentStatus.isRunBlock()) {
|
currentStatus.setRunBlock(false);
|
News.info("[WCS Debug] 站点{}堵塞标记已清除", stationId);
|
}
|
} finally {
|
unlockStations(stationId);
|
}
|
}
|
|
private boolean checkTaskNoInArea(Integer taskNo) {
|
Object fakeTaskNoAreaObj = redisUtil.get(RedisKeyType.FAKE_TASK_NO_AREA.key);
|
if (fakeTaskNoAreaObj == null) {
|
return false;
|
}
|
|
JSONObject data = JSON.parseObject(String.valueOf(fakeTaskNoAreaObj));
|
Integer start = data.getInteger("start");
|
Integer end = data.getInteger("end");
|
|
if (taskNo >= start && taskNo <= end) {
|
return true;
|
}
|
|
return false;
|
}
|
}
|