package com.zy.core.thread.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 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.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 com.zy.core.thread.impl.v5.StationV5SegmentExecutor; import com.zy.core.utils.DeviceLogRedisKeyBuilder; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @Data @Slf4j public class ZyStationV5Thread implements Runnable, com.zy.core.thread.StationThread { private List statusList = new ArrayList<>(); private DeviceConfig deviceConfig; private RedisUtil redisUtil; private ZyStationConnectDriver zyStationConnectDriver; private int deviceLogCollectTime = 200; private boolean initStatus = false; private long deviceDataLogTime = System.currentTimeMillis(); private ExecutorService executor = Executors.newFixedThreadPool(9999); private StationV5SegmentExecutor segmentExecutor; public ZyStationV5Thread(DeviceConfig deviceConfig, RedisUtil redisUtil) { this.deviceConfig = deviceConfig; this.redisUtil = redisUtil; this.segmentExecutor = new StationV5SegmentExecutor(deviceConfig, redisUtil, this::sendCommand); } @Override @SuppressWarnings("InfiniteLoopStatement") public void run() { this.connect(); deviceLogCollectTime = Utils.getDeviceLogCollectTime(); Thread readThread = new Thread(() -> { while (true) { try { if (initStatus) { deviceLogCollectTime = Utils.getDeviceLogCollectTime(); } readStatus(); Thread.sleep(100); } catch (Exception e) { log.error("StationV5Thread Fail", e); } } }, "DevpRead-" + deviceConfig.getDeviceNo()); 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(() -> segmentExecutor.execute(cmd)); } Thread.sleep(100); } catch (Exception e) { log.error("StationV5Process Fail", e); } } }, "DevpProcess-" + deviceConfig.getDeviceNo()); processThread.start(); } private void readStatus() { if (zyStationConnectDriver == null) { return; } if (statusList.isEmpty()) { BasDevpService basDevpService = null; try { basDevpService = SpringUtils.getBean(BasDevpService.class); } catch (Exception ignore) { } if (basDevpService == null) { return; } BasDevp basDevp = basDevpService .getOne(new QueryWrapper().eq("devp_no", deviceConfig.getDeviceNo())); if (basDevp == null) { return; } List list = JSONObject.parseArray(basDevp.getStationList(), ZyStationStatusEntity.class); for (ZyStationStatusEntity entity : list) { StationProtocol stationProtocol = new StationProtocol(); stationProtocol.setStationId(entity.getStationId()); statusList.add(stationProtocol); } initStatus = true; } List 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()); stationProtocol.setTaskWriteIdx(statusEntity.getTaskWriteIdx()); } 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(DeviceLogRedisKeyBuilder.build(deviceDataLog), 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 getStatus() { return statusList; } @Override public Map getStatusMap() { Map 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 && !stationId.equals(targetStationId)) { List nodes = calcPathNavigateNodes(stationId, targetStationId); List path = new ArrayList<>(); List liftTransferPath = new ArrayList<>(); for (NavigateNode n : nodes) { JSONObject v = JSONObject.parseObject(n.getNodeValue()); if (v == null) { continue; } Integer stationNo = v.getInteger("stationId"); if (stationNo == null) { continue; } path.add(stationNo); if (Boolean.TRUE.equals(n.getIsLiftTransferPoint())) { liftTransferPath.add(stationNo); } } stationCommand.setNavigatePath(path); stationCommand.setLiftTransferPath(liftTransferPath); } 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 statusListEntity = zyStationConnectDriver.getStatus(); ZyStationStatusEntity matched = null; if (statusListEntity != null) { for (ZyStationStatusEntity entity : statusListEntity) { if (entity.getStationId() != null && entity.getStationId().equals(command.getStationId())) { matched = entity; 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.save(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 calcPathNavigateNodes(Integer startStationId, Integer targetStationId) { NavigateUtils navigateUtils = SpringUtils.getBean(NavigateUtils.class); if (navigateUtils == null) { return new ArrayList<>(); } return navigateUtils.calcByStationId(startStationId, targetStationId); } }