#
Junjie
2025-07-10 fbc1ee007b2cbf95d33b6950fc95c0b4a34027d6
src/main/java/com/zy/core/thread/ShuttleThread.java
@@ -1,275 +1,12 @@
package com.zy.core.thread;
import HslCommunication.Core.Transfer.DataFormat;
import HslCommunication.Core.Types.OperateResult;
import HslCommunication.Core.Types.OperateResultExOne;
import HslCommunication.ModBus.ModbusTcpNet;
import HslCommunication.Profinet.Siemens.SiemensPLCS;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import com.alibaba.fastjson.JSON;
import com.core.common.DateUtils;
import com.core.common.RadixTools;
import com.core.exception.CoolException;
import com.zy.core.News;
import com.zy.core.ThreadHandler;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.OutputQueue;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.ShuttleStatusType;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.ShuttleSlave;
import com.zy.core.model.SteSlave;
import com.zy.core.model.Task;
import com.zy.core.model.command.ShuttleCommand;
import com.zy.core.model.command.SteCommand;
import com.zy.core.model.protocol.ShuttleProtocol;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import com.zy.core.properties.DeviceConfig;
import java.text.MessageFormat;
import java.util.Date;
public interface ShuttleThread extends ThreadHandler {
/**
 * 四向穿梭车线程
 */
@Data
@Slf4j
public class ShuttleThread implements  Runnable, ThreadHandler {
    DeviceConfig getDeviceConfig();
    private ModbusTcpNet modbusTcpNet;
    private ShuttleSlave slave;
    private ShuttleProtocol shuttleProtocol;
    private SiemensS7Net siemensS7Net;
    void stopThread();
    public ShuttleThread(ShuttleSlave slave) {
        this.slave = slave;
    }
    @Override
    public void run() {
        this.connect();
        while (true) {
            try {
                int step = 1;
                Task task = MessageQueue.poll(SlaveType.Shuttle, slave.getId());
                if (task != null) {
                    step = task.getStep();
                }
                switch (step) {
                    // 读数据
                    case 1:
                        readStatus();
                        break;
                    // 写入数据
                    case 2:
                        write((ShuttleCommand) task.getData());
                        break;
                    default:
                        break;
                }
                Thread.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    @Override
    public boolean connect() {
        boolean result = false;
        //-------------------------四向穿梭车连接方法------------------------//
        modbusTcpNet = new ModbusTcpNet(slave.getIp(), slave.getPort(), (byte) 0x01);
        // 当你需要指定格式的数据解析时,就需要设置下面的这个信息
        modbusTcpNet.setDataFormat(DataFormat.ABCD);
        OperateResult connect = modbusTcpNet.ConnectServer();
        if(connect.IsSuccess){
            result = true;
            OutputQueue.CRN.offer(MessageFormat.format( "【{0}】四向穿梭车plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            log.info("四向穿梭车plc连接成功 ===>> [id:{}] [ip:{}] [port:{}] ", slave.getId(), slave.getIp(), slave.getPort());
        } else {
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】四向穿梭车plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            log.error("四向穿梭车plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}] ", slave.getId(), slave.getIp(), slave.getPort());
        }
        modbusTcpNet.ConnectClose();
        //-------------------------四向穿梭车连接方法------------------------//
        return result;
    }
    @Override
    public void close() {
    }
    private void readStatus() {
        try {
            OperateResultExOne<byte[]> result = modbusTcpNet.Read("0", (short) 17);
            if (result.IsSuccess) {
                if (null == shuttleProtocol) {
                    shuttleProtocol = new ShuttleProtocol();
                    shuttleProtocol.setShuttleNo(slave.getId().shortValue());
                }
                //----------设置四向穿梭车状态-----------
                //获取数据
                byte[] content = result.Content;
                //--------控制字--------
                //控制指令字
                shuttleProtocol.setCommandWord(modbusTcpNet.getByteTransform().TransUInt16(content, 0));
                //启始二维编号
                shuttleProtocol.setStartCodeNum(modbusTcpNet.getByteTransform().TransUInt16(content, 2));
                //中间二维编号
                shuttleProtocol.setMiddleCodeNum(modbusTcpNet.getByteTransform().TransUInt16(content, 4));
                //目标二维编号
                shuttleProtocol.setDistCodeNum(modbusTcpNet.getByteTransform().TransUInt16(content, 6));
                //起点到目标点的距离长度
                shuttleProtocol.setStartToDistDistance(modbusTcpNet.getByteTransform().TransInt32(content, 8));
                //中间点到目标点的距离长度
                shuttleProtocol.setMiddleToDistDistance(modbusTcpNet.getByteTransform().TransInt32(content, 12));
                //小车运行方向
                shuttleProtocol.setRunDirection(modbusTcpNet.getByteTransform().TransUInt16(content, 16));
                //托盘顶升
                shuttleProtocol.setPalletLift(modbusTcpNet.getByteTransform().TransUInt16(content,18));
                //小车强制移动距离
                shuttleProtocol.setForceMoveDistance(modbusTcpNet.getByteTransform().TransInt32(content, 20));
                //充电开关
                shuttleProtocol.setChargeSwitch(modbusTcpNet.getByteTransform().TransUInt16(content,24));
                //小车IO控制
                shuttleProtocol.setIOControl(modbusTcpNet.getByteTransform().TransUInt16(content,26));
                //小车运行速度
                shuttleProtocol.setRunSpeed(modbusTcpNet.getByteTransform().TransUInt16(content,28));
                //小车雷达备用
                shuttleProtocol.setRadarTmp(modbusTcpNet.getByteTransform().TransUInt16(content,30));
                //指令结束位
                shuttleProtocol.setCommandEnd(modbusTcpNet.getByteTransform().TransUInt16(content,32));
                //---------状态字---------
//                shuttleProtocol.setBusyStatus(modbusTcpNet.getByteTransform().TransUInt16(content,32));
                ///设置四向穿梭车状态-end
                OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
                //读取四向穿梭车设备信息,提供查询
                //.....
                // 根据实时信息更新数据库
                //.....
            }else {
                OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】{1}四向穿梭车plc状态信息失败", DateUtils.convert(new Date()), slave.getId()));
                throw new CoolException(MessageFormat.format( "四向穿梭车plc状态信息失败 ===>> [id:{0}] [ip:{1}] [port:{2}]", slave.getId(), slave.getIp(), slave.getPort()));
            }
        } catch (Exception e) {
            OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】四向穿梭车plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            initShuttle();
        }
    }
    private boolean write(ShuttleCommand command){
        if (null == command) {
            News.error("四向穿梭车写入命令为空");
            return false;
        }
        //判断小车是否在充电
        SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
        if (devpThread.charge1){
        }
        command.setShuttleNo(slave.getId());
        OperateResult result = null;
        // 开始任务
        //...
        try {
            // 日志记录
            if (!command.getComplete() && command.getTaskMode() != 0) {
                //日志记录保存到数据库中
                //.....
            }
        } catch (Exception ignore) {}
        if (result != null && result.IsSuccess) {
            // 维护数据库排列层
//            if (!steProtocol.getWaiting()) {
//                if (!Cools.isEmpty(command.getRow(), command.getBay(), command.getLev())) {
//                    this.modifyPos(command.getRow().intValue(), command.getBay().intValue(), command.getLev().intValue());
//                }
//            }
            News.info("四向穿梭车命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command));
            OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command)));
            return true;
        } else {
            OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】写入四向穿梭车plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            News.error("写入四向穿梭车plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
            return false;
        }
    }
    /**
     * 初始化四向穿梭车
     */
    private void initShuttle() {
        if (null == shuttleProtocol) {
            shuttleProtocol = new ShuttleProtocol();
        }
        shuttleProtocol.setShuttleNo(slave.getId().shortValue());
        shuttleProtocol.setBusyStatus(ShuttleStatusType.BUSY);
        shuttleProtocol.setCurrentCode("0");
    }
    /******************************************************************************************/
    /**************************************** 测试专用 *****************************************/
    /*****************************************************************************************/
    public static void main(String[] args) throws InterruptedException {
        ShuttleSlave slave = new ShuttleSlave();
        slave.setId(1);
        slave.setIp("192.168.4.24");
        slave.setPort(502);
        ShuttleThread thread = new ShuttleThread(slave);
        thread.connect();
        thread.readStatus();
        System.out.println(JSON.toJSONString(thread.shuttleProtocol));
        // 任务作业
//        SteCommand command = new SteCommand();
//        command.setSteNo(1); // 堆垛机编号
//        Random random = new Random();
//        int taskNo = random.nextInt(9090);
//        command.setTaskNo(taskNo); // 工作号
//        command.setTaskMode(SteTaskModeType.MOVE_LEFT); // 任务模式
//        thread.write(command);
        // 任务完成
//        SteCommand command = new SteCommand();
//        command.setSteNo(1); // 堆垛机编号
//        command.setComplete(Boolean.TRUE); // 任务模式
//        thread.write(command);
        // 控制模式
//        SteCommand command = new SteCommand();
//        command.setControlMode((short) 1);
//        thread.write(command);
        // 复位信号
//        SteCommand command = new SteCommand();
//        command.setReset(Boolean.TRUE);
//        thread.write(command);
        // 删除指令
//        SteCommand command = new SteCommand();
//        command.setDelete(Boolean.TRUE);
//        thread.write(command);
        // 穿梭车运行禁止
//        SteCommand command = new SteCommand();
//        command.setRun((short)0);
//        thread.write(command);
    }
}