#
luxiaotao1123
2020-12-28 678f43f99d4fe259c6ce3dabbc2563776c2a25f1
src/main/java/com/zy/core/thread/MelsecCrnThread.java
@@ -2,12 +2,14 @@
import HslCommunication.Core.Types.OperateResult;
import HslCommunication.Core.Types.OperateResultExOne;
import HslCommunication.Profinet.Siemens.SiemensPLCS;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import HslCommunication.Profinet.Melsec.MelsecMcNet;
import com.alibaba.fastjson.JSON;
import com.core.common.Arith;
import com.core.common.DateUtils;
import com.core.common.SpringUtils;
import com.zy.asrs.entity.BasCrnOpt;
import com.zy.asrs.entity.BasCrnp;
import com.zy.asrs.service.BasCrnOptService;
import com.zy.asrs.service.BasCrnpService;
import com.zy.core.CrnThread;
import com.zy.core.cache.MessageQueue;
@@ -23,6 +25,7 @@
import lombok.extern.slf4j.Slf4j;
import java.text.MessageFormat;
import java.util.Calendar;
import java.util.Date;
/**
@@ -33,10 +36,12 @@
@Slf4j
public class MelsecCrnThread implements Runnable, CrnThread {
    private SiemensS7Net siemensNet;
    private MelsecMcNet melsecMcNet;
    private CrnSlave slave;
    private CrnProtocol crnProtocol;
    private boolean resetFlag = false;
    private short heartBeatVal = 1;
    private int heartTimes = 0;
    public MelsecCrnThread(CrnSlave slave) {
        this.slave = slave;
@@ -83,6 +88,12 @@
                    default:
                        break;
                }
                // 心跳 2s一次
                heartTimes++;
                if (Arith.remainder(heartTimes, 4) == 0) {
                    heartbeat();
                    heartTimes = 0;
                }
                Thread.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
@@ -94,19 +105,50 @@
    @Override
    public boolean connect() {
        boolean result = false;
        siemensNet = new SiemensS7Net(SiemensPLCS.S300, slave.getIp());
        siemensNet.setRack(slave.getRack().byteValue());
        siemensNet.setSlot(slave.getSlot().byteValue());
        OperateResult connect = siemensNet.ConnectServer();
        melsecMcNet = new MelsecMcNet(slave.getIp(), slave.getPort());
        OperateResult connect = melsecMcNet.ConnectServer();
        if(connect.IsSuccess){
            result = true;
            OutputQueue.CRN.offer(MessageFormat.format( "【{0}】堆垛机plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            log.info("堆垛机plc连接成功 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
            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}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            log.error("堆垛机plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
            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());
        }
        siemensNet.ConnectClose();
        // 命令下发区 --------------------------------------------------------------------------
        /**
         *      array[1] = command.getSourcePosY(); // 列
         *         array[2] = command.getSourcePosZ(); // 层
         *         array[3] = command.getSourcePosX(); // 排
         *         array[4] = command.getDestinationPosY(); // 列
         *         array[5] = command.getDestinationPosZ();  // 层
         *         array[6] = command.getDestinationPosX(); // 排
         *         array[7] = command.getTaskNo();
         */
        Date date = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        CrnCommand crnCommand = new CrnCommand();
        crnCommand.setCrnNo(slave.getId()); // 堆垛机编号
        crnCommand.setTaskMode(CrnTaskModeType.TIMING); // 任务模式:  设置时间
        crnCommand.setSourcePosY((short) cal.get(Calendar.YEAR));     // 年:1980~2079
        crnCommand.setSourcePosZ((short) (cal.get(Calendar.MONTH)+1));     // 月:1~12
        crnCommand.setSourcePosX((short) cal.get(Calendar.DATE));     // 日:1~31
        crnCommand.setDestinationPosY((short) cal.get(Calendar.HOUR_OF_DAY));     // 时:0~23
        crnCommand.setDestinationPosZ((short) cal.get(Calendar.MINUTE));     // 分:0~59
        crnCommand.setDestinationPosX((short) cal.get(Calendar.SECOND));     // 秒:0~59
        crnCommand.setTaskNo((short) (cal.get(Calendar.DAY_OF_WEEK) - 1));     // 星期:0(日)~6(六)
        crnCommand.setTaskSend((short) 1);
        crnCommand.setAckFinish((short) 0);
        if (write(crnCommand)) {
            log.info("堆垛机plc校对时间成功 ===>> [id:{}] [ip:{}] [port:{}] ", slave.getId(), slave.getIp(), slave.getPort());
        }
        melsecMcNet.ConnectClose();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        return result;
    }
@@ -114,36 +156,33 @@
     * 读取状态
     */
    private void readStatus(){
        OperateResultExOne<byte[]> result = siemensNet.Read("DB8.18", (short) 62);
        OperateResultExOne<byte[]> result = melsecMcNet.Read("D1119", (short) 58);
        if (result.IsSuccess) {
            if (null == crnProtocol) {
                crnProtocol = new CrnProtocol();
            }
            crnProtocol.setMode(siemensNet.getByteTransform().TransInt16(result.Content, 0));
            crnProtocol.setTaskNo(siemensNet.getByteTransform().TransInt16(result.Content, 2));
            crnProtocol.setStatus(siemensNet.getByteTransform().TransInt16(result.Content, 4));
            crnProtocol.setBay(siemensNet.getByteTransform().TransInt16(result.Content, 6));
            crnProtocol.setLevel(siemensNet.getByteTransform().TransInt16(result.Content, 8));
            crnProtocol.setForkPos(siemensNet.getByteTransform().TransInt16(result.Content, 10));
            crnProtocol.setLiftPos(siemensNet.getByteTransform().TransInt16(result.Content, 12));
            crnProtocol.setWalkPos(siemensNet.getByteTransform().TransInt16(result.Content, 14));
//            crnProtocol.setTaskFinish(siemensNet.getByteTransform().TransInt16(result.Content, 16));
            crnProtocol.setLoaded(siemensNet.getByteTransform().TransInt16(result.Content, 18));
            crnProtocol.setAlarm1(siemensNet.getByteTransform().TransInt16(result.Content, 20));
            // 异常信息
            crnProtocol.setError1(siemensNet.getByteTransform().TransBool(result.Content, 22, 2));
            crnProtocol.setError2(siemensNet.getByteTransform().TransBool(result.Content, 24, 2));
            crnProtocol.setError3(siemensNet.getByteTransform().TransBool(result.Content, 26, 2));
            crnProtocol.setError4(siemensNet.getByteTransform().TransBool(result.Content, 28, 2));
            crnProtocol.setError5(siemensNet.getByteTransform().TransBool(result.Content, 30, 2));
            crnProtocol.setError6(siemensNet.getByteTransform().TransBool(result.Content, 32, 2));
            crnProtocol.setXSpeed(siemensNet.getByteTransform().TransSingle(result.Content, 34));
            crnProtocol.setYSpeed(siemensNet.getByteTransform().TransSingle(result.Content, 38));
            crnProtocol.setZSpeed(siemensNet.getByteTransform().TransSingle(result.Content, 42));
            crnProtocol.setXDistance(siemensNet.getByteTransform().TransSingle(result.Content, 46));
            crnProtocol.setYDistance(siemensNet.getByteTransform().TransSingle(result.Content, 50));
            crnProtocol.setXDuration(siemensNet.getByteTransform().TransSingle(result.Content, 54));
            crnProtocol.setYDuration(siemensNet.getByteTransform().TransSingle(result.Content, 58));
            crnProtocol.setTaskNo(melsecMcNet.getByteTransform().TransInt16(result.Content, 0));
            crnProtocol.setMode(melsecMcNet.getByteTransform().TransInt16(result.Content, 2));
            crnProtocol.setStatus(melsecMcNet.getByteTransform().TransInt16(result.Content, 4));
            crnProtocol.setBay(melsecMcNet.getByteTransform().TransInt16(result.Content, 6));
            crnProtocol.setLevel(melsecMcNet.getByteTransform().TransInt16(result.Content, 8));
            crnProtocol.setForkPos(melsecMcNet.getByteTransform().TransInt16(result.Content, 10));
            crnProtocol.setLiftPos(melsecMcNet.getByteTransform().TransInt16(result.Content, 12));
            crnProtocol.setWalkPos(melsecMcNet.getByteTransform().TransInt16(result.Content, 14));
            crnProtocol.setFingerPos(melsecMcNet.getByteTransform().TransInt16(result.Content, 16));
            crnProtocol.setLoaded(melsecMcNet.getByteTransform().TransInt16(result.Content, 18));
            crnProtocol.setAlarm1(melsecMcNet.getByteTransform().TransInt16(result.Content, 20));
            crnProtocol.setTemp1(melsecMcNet.getByteTransform().TransInt16(result.Content, 22));
            crnProtocol.setTemp2(melsecMcNet.getByteTransform().TransInt16(result.Content, 24));
            crnProtocol.setTemp3(melsecMcNet.getByteTransform().TransInt16(result.Content, 26));
            crnProtocol.setTemp4(melsecMcNet.getByteTransform().TransInt16(result.Content, 28));
            crnProtocol.setXSpeed(melsecMcNet.getByteTransform().TransSingle(result.Content, 30));
            crnProtocol.setYSpeed(melsecMcNet.getByteTransform().TransSingle(result.Content, 34));
            crnProtocol.setZSpeed(melsecMcNet.getByteTransform().TransSingle(result.Content, 38));
            crnProtocol.setXDistance(melsecMcNet.getByteTransform().TransSingle(result.Content, 42));
            crnProtocol.setYDistance(melsecMcNet.getByteTransform().TransSingle(result.Content, 46));
            crnProtocol.setXDuration(melsecMcNet.getByteTransform().TransSingle(result.Content, 50));
            crnProtocol.setYDuration(melsecMcNet.getByteTransform().TransSingle(result.Content, 54));
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
@@ -163,13 +202,14 @@
            BasCrnpService basCrnpService = SpringUtils.getBean(BasCrnpService.class);
            BasCrnp basCrnp = new BasCrnp();
            basCrnp.setCrnNo(slave.getId());
            crnProtocol.setAlarm1((short) (crnProtocol.getAlarm1() + 1000));
            if (!basCrnpService.updateById(crnProtocol.toSqlModel(basCrnp))){
                log.error("堆垛机plc数据库更新失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
                log.error("堆垛机plc数据库更新失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
            }
        } else {
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】读取堆垛机plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            log.error("读取堆垛机plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
            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());
        }
    }
@@ -181,32 +221,78 @@
            log.error("堆垛机写入命令为空");
            return false;
        }
        if (command.getAckFinish() == 1) {
            command.setTaskSend((short) 0);
        } else if (command.getAckFinish() == 0) {
            command.setTaskSend((short) 1);
        }
        command.setCrnNo(slave.getId());
        short[] array = new short[9];
        array[0] = command.getAckFinish();
        array[1] = command.getTaskNo();
        array[2] = command.getTaskMode();
        array[3] = command.getSourcePosX();
        array[4] = command.getSourcePosY();
        array[5] = command.getSourcePosZ();
        array[6] = command.getDestinationPosX();
        array[7] = command.getDestinationPosY();
        array[8] = command.getDestinationPosZ();
        OperateResult result = siemensNet.Write("DB8.0", array);
        short[] array = new short[10];
        array[0] = command.getTaskMode();
        array[1] = command.getSourcePosY(); // 列
        array[2] = command.getSourcePosZ(); // 层
        array[3] = command.getSourcePosX(); // 排
        array[4] = command.getDestinationPosY(); // 列
        array[5] = command.getDestinationPosZ();  // 层
        array[6] = command.getDestinationPosX(); // 排
        array[7] = command.getTaskNo();
        array[8] = command.getTaskSend();
        array[9] = command.getAckFinish();
        OperateResult result = melsecMcNet.Write("D1001", array);
        if (result.IsSuccess) {
            log.info("堆垛机命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command));
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command)));
            try {
                // 日志记录
                BasCrnOptService bean = SpringUtils.getBean(BasCrnOptService.class);
                BasCrnOpt basCrnOpt = new BasCrnOpt(
                        command.getTaskNo().intValue(),    // 任务号
                        command.getCrnNo(),    // 堆垛机[非空]
                        new Date(),    // 下发时间
                        command.getTaskModeType().toString(),    // 模式
                        command.getSourcePosX().intValue(),    // 源排
                        command.getSourcePosY().intValue(),    // 源列
                        command.getSourcePosZ().intValue(),    // 源层
                        null,    // 源站
                        command.getDestinationPosX().intValue(),    // 目标排
                        command.getDestinationPosY().intValue(),    // 目标列
                        command.getDestinationPosZ().intValue(),    // 目标层
                        null,    // 目标站
                        null,    // 响应结果
                        null,    // 修改时间
                        null    // 修改人员
                );
                bean.insert(basCrnOpt);
            } catch (Exception ignore) {}
            return true;
        } else {
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】写入堆垛机plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            log.error("写入堆垛机plc数据失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
            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());
            return false;
        }
    }
    /**
     * 心跳
     */
    private void heartbeat(){
        if (heartBeatVal == 1) {
            heartBeatVal = 0;
        } else {
            heartBeatVal = 1;
        }
        OperateResult write = melsecMcNet.Write("D1000", heartBeatVal);
        if (!write.IsSuccess) {
            log.error("输送线plc编号={} 心跳失败", slave.getId());
        }
    }
    @Override
    public void close() {
        siemensNet.ConnectClose();
        melsecMcNet.ConnectClose();
    }
    /******************************************************************************************/
@@ -216,8 +302,6 @@
        CrnSlave slave = new CrnSlave();
        slave.setId(1);
        slave.setIp("192.168.6.9");
        slave.setRack(0);
        slave.setSlot(0);
        MelsecCrnThread crnThread = new MelsecCrnThread(slave);
        crnThread.connect();
        crnThread.readStatus();