//package com.zy.core.thread; // //import HslCommunication.Core.Types.OperateResult; //import HslCommunication.Core.Types.OperateResultExOne; //import HslCommunication.Profinet.Melsec.MelsecMcNet; //import com.alibaba.fastjson.JSON; //import com.core.common.DateUtils; //import com.core.common.SpringUtils; //import com.core.exception.CoolException; //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.common.utils.News; //import com.zy.core.CrnThread; //import com.zy.core.ThreadHandler; //import com.zy.core.cache.MessageQueue; //import com.zy.core.cache.OutputQueue; //import com.zy.core.enums.CrnStatusType; //import com.zy.core.enums.CrnTaskModeType; //import com.zy.core.enums.SlaveType; //import com.zy.core.model.CrnSlave; //import com.zy.core.model.Task; //import com.zy.core.model.command.CrnCommand; //import com.zy.core.model.protocol.CrnProtocol; //import lombok.Data; //import lombok.extern.slf4j.Slf4j; // //import java.text.MessageFormat; //import java.util.Date; // ///** // * 堆垛机线程 // * Created by vincent on 2020/8/4 // */ //@Data //@Slf4j //public class MelsecCrnThread implements Runnable, ThreadHandler, CrnThread //{ // // private MelsecMcNet melsecMcNet; // private CrnSlave slave; // private CrnProtocol crnProtocol; // private short heartBeatVal = 1; // private boolean resetFlag = false; // // /** // * 堆垛机是否在回原点运动中标记 // */ // private boolean backHpFlag = false; // // public MelsecCrnThread(CrnSlave slave) { // this.slave = slave; // } // // @Override // @SuppressWarnings("InfiniteLoopStatement") // public void run() { // this.connect(); //// try { //// Thread.sleep(2000); //// } catch (InterruptedException e) { //// e.printStackTrace(); //// } // while (true) { // try { // int step = 1; // Task task = MessageQueue.poll(SlaveType.Crn, slave.getId()); // if (task != null) { // step = task.getStep(); // } // switch (step) { // // 读数据 // case 1: // readStatus(); // break; // // 写入数据 // case 2: // write((CrnCommand) task.getData()); // break; // // 复位 // case 3: // CrnCommand command = (CrnCommand) task.getData(); // if (null == command) { // command = new CrnCommand(); // } // command.setCrnNo(slave.getId()); // 堆垛机编号 // command.setTaskNo((short) 0); // 工作号 // command.setAckFinish((short) 1); // 任务完成确认位 // command.setTaskMode(CrnTaskModeType.NONE); // 任务模式 //// command.setSourcePosX((short)0); // 源库位排 //// command.setSourcePosY((short)0); // 源库位列 //// command.setSourcePosZ((short)0); // 源库位层 //// command.setDestinationPosX((short)0); // 目标库位排 //// command.setDestinationPosY((short)0); // 目标库位列 //// command.setDestinationPosZ((short)0); // 目标库位层 // write(command); // break; // default: // break; // } // // 心跳 // heartbeat(); // Thread.sleep(500); // } catch (Exception e) { // e.printStackTrace(); // } // // } // } // // /** // * 初始化堆垛机状态 // */ // private void initCrn() { // if (null == crnProtocol) { // crnProtocol = new CrnProtocol(); // } // crnProtocol.setMode((short) -1); //// crnProtocol.setTaskNo((short)0); // crnProtocol.setStatus((short)-1); // crnProtocol.setBay((short)0); // crnProtocol.setLevel((short)0); // crnProtocol.setForkPos((short) -1); // crnProtocol.setLiftPos((short) -1); // crnProtocol.setWalkPos((short)0); // crnProtocol.setLoaded((short)0); // crnProtocol.setAlarm((short)0); // crnProtocol.setxSpeed((short)0); // crnProtocol.setySpeed((short)0); // crnProtocol.setzSpeed((short)0); // crnProtocol.setxDistance((short)0); // crnProtocol.setyDistance((short)0); // crnProtocol.setxDuration((short)0); // crnProtocol.setyDuration((short)0); // } // // @Override // public boolean connect() { // boolean result = false; // 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}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); // News.info("MelsecCrn"+" - 1"+" - 堆垛机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())); // News.error("MelsecCrn"+" - 2"+" - 堆垛机plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); // initCrn(); // } //// melsecMcNet.ConnectClose(); // return result; // } // // /** // * 读取状态 // */ // private void readStatus(){ // try { //// if (this.slave.getId() == 1 && flag1.equals(0)) { //// Thread.sleep(3000); //// flag1=1; //// System.out.println("==="); //// } // OperateResultExOne result = melsecMcNet.Read("D1035", (short) 56); // if (result.IsSuccess) { // if (null == crnProtocol) { // crnProtocol = new CrnProtocol(); // crnProtocol.setCrnNo(slave.getId()); // } // crnProtocol.setMode(melsecMcNet.getByteTransform().TransInt16(result.Content, 0)); // crnProtocol.setTaskNo(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.setLoaded(melsecMcNet.getByteTransform().TransInt16(result.Content, 16)); // crnProtocol.setAlarm(melsecMcNet.getByteTransform().TransInt16(result.Content, 18)); // crnProtocol.setTemp1(melsecMcNet.getByteTransform().TransInt16(result.Content, 20)); // crnProtocol.setTemp2(melsecMcNet.getByteTransform().TransInt16(result.Content, 22)); // crnProtocol.setTemp3(melsecMcNet.getByteTransform().TransInt16(result.Content, 24)); // crnProtocol.setTemp4(melsecMcNet.getByteTransform().TransInt16(result.Content, 26)); // crnProtocol.setxSpeed(melsecMcNet.getByteTransform().TransInt16(result.Content, 28)); // crnProtocol.setySpeed(melsecMcNet.getByteTransform().TransInt16(result.Content, 32)); // crnProtocol.setzSpeed(melsecMcNet.getByteTransform().TransInt16(result.Content, 36)); // crnProtocol.setxDistance(melsecMcNet.getByteTransform().TransInt16(result.Content, 40)); // crnProtocol.setyDistance(melsecMcNet.getByteTransform().TransInt16(result.Content, 44)); // crnProtocol.setxDuration(melsecMcNet.getByteTransform().TransInt16(result.Content, 48)); // crnProtocol.setyDuration(melsecMcNet.getByteTransform().TransInt16(result.Content, 52)); // // OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId())); // // // 复位信号 // if (crnProtocol.getStatusType().equals(CrnStatusType.WAITING_ONE)) { // News.error("MelsecCrn"+" - 3"+" ---------第一步、[堆垛机号:{}][工作号:{}]==>> 状态为90,等待确认!!",slave.getId(),crnProtocol.getTaskNo()); // if (resetFlag) { // if(crnProtocol.getTaskNo()==9999){ // backHpFlag = false; // } // CrnCommand crnCommand = new CrnCommand(); // crnCommand.setAckFinish((short)1); // if (write(crnCommand)) { // resetFlag = false; // } // } // } // // // 根据实时信息更新数据库 // BasCrnpService basCrnpService = SpringUtils.getBean(BasCrnpService.class); // BasCrnp basCrnp = new BasCrnp(); // basCrnp.setCrnErr(crnProtocol.getAlarm()==null?0:crnProtocol.getAlarm().longValue()); // basCrnp.setCrnNo(slave.getId()); // basCrnp.setCrnSts((int)crnProtocol.getMode()); // if (!basCrnpService.updateById(crnProtocol.toSqlModel(basCrnp))){ // News.error("MelsecCrn"+" - 4"+" - 堆垛机plc数据库更新失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); // } // // } else { // OutputQueue.CRN.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) { // e.printStackTrace(); // OutputQueue.CRN.offer(MessageFormat.format("【{0}】读取堆垛机plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); // News.error("MelsecCrn"+" - 5"+" - 读取堆垛机plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); // initCrn(); // } // // } // // /** // * 写入数据 // */ // private boolean write(CrnCommand command){ // if (null == command) { // News.error("MelsecCrn"+" - 6"+" - 堆垛机写入命令为空"); // return false; // } // //// OperateResult result = null; //// try{ //// Integer exeCount=0; //// do{ //// command.setCrnNo(slave.getId()); //// short[] array = new short[10]; //// 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(); //// array[9] = command.getCommand(); //// result = melsecMcNet.Write("D0", array); //// if(result.IsSuccess) { //// if (command.getAckFinish() == 0) { //// short commandFinish = 1; //// result = melsecMcNet.Write("D9", commandFinish); //// if(result.IsSuccess){ //// //写任务确认返回成功后,查询确认一次 //// Thread.sleep(200); //// OperateResultExOne result1 = melsecMcNet.Read("D9", (short)2); //// if(result1.IsSuccess){ //// short commandVal = melsecMcNet.getByteTransform().TransInt16(result1.Content,2); //// if(commandVal==1){ //// break; //// } else { //// exeCount++; //// } //// } else{ //// exeCount++; //// } //// }else{ //// exeCount++; //// } //// } //// }else{ //// exeCount++; //// } //// Thread.sleep(200); //// }while(exeCount>3); //// }catch (Exception e){ //// //// } // // command.setCrnNo(slave.getId()); // short[] array = new short[10]; // 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(); // array[9] = command.getCommand(); // OperateResult result = melsecMcNet.Write("D1001", array); // // if (command.getAckFinish() == 0) { // short commandFinish = 1; // result = melsecMcNet.Write("D1010", commandFinish); // } // // 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.save(basCrnOpt); // } catch (Exception ignore) {} // // if (result != null && result.IsSuccess) { // News.info("MelsecCrn"+" - 7"+" - 堆垛机命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command)); // OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command))); // return true; // } else { // OutputQueue.CRN.offer(MessageFormat.format("【{0}】写入堆垛机plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); // News.error("MelsecCrn"+" - 8"+" - 写入堆垛机plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); // return false; // } // } // // @Override // public void close() { // melsecMcNet.ConnectClose(); // } // // /** // * 心跳 // */ // private void heartbeat(){ // if (heartBeatVal >= 30000) { // heartBeatVal = -30000; // } else { // heartBeatVal =(short) (heartBeatVal+1); // } // OperateResult write = melsecMcNet.Write("D1011", heartBeatVal); //// OperateResult write1 = melsecMcNet.Write("D1001", (short) 0); //// OperateResult write2 = melsecMcNet.Write("D1002", (short) 0); //// OperateResult write3 = melsecMcNet.Write("D1003", (short) 0); //// OperateResult write4 = melsecMcNet.Write("D1004", (short) 0); //// OperateResult write5 = melsecMcNet.Write("D1005", (short) 0); //// OperateResult write6 = melsecMcNet.Write("D1006", (short) 0); //// OperateResult write7 = melsecMcNet.Write("D1007", (short) 0); //// OperateResult write8 = melsecMcNet.Write("D1008", (short) 0); //// OperateResult write9 = melsecMcNet.Write("D1009", (short) 0); //// OperateResult write10 = melsecMcNet.Write("D1010", (short) 0); // if (!write.IsSuccess) { // News.error("MelsecCrn"+" - 9"+" - 堆垛机plc心跳通讯失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); // } // } // // // /******************************************************************************************/ // /**************************************** 测试专用 *****************************************/ // /*****************************************************************************************/ // public static void main(String[] args) throws InterruptedException { // CrnSlave slave = new CrnSlave(); // slave.setId(1); // slave.setIp("192.168.3.39"); // slave.setPort(5015); // slave.setRack(0); // slave.setSlot(0); // MelsecCrnThread melsecCrnThread = new MelsecCrnThread(slave); // melsecCrnThread.connect(); // melsecCrnThread.readStatus(); // System.out.println(JSON.toJSONString(melsecCrnThread.crnProtocol)); // // // 1.入库 源和目标都发 //// CrnCommand command = new CrnCommand(); //// command.setCrnNo(1); // 堆垛机编号 //// command.setTaskNo((short) 0); // 工作号 //// command.setAckFinish((short) 0); // 任务完成确认位 //// command.setTaskMode(CrnTaskModeType.PAKIN); // 任务模式 //// command.setSourcePosX((short) 1); // 源库位排 //// command.setSourcePosY((short) 0); // 源库位列 //// command.setSourcePosZ((short) 1); // 源库位层 //// command.setDestinationPosX((short) 2); // 目标库位排 //// command.setDestinationPosY((short) 3); // 目标库位列 //// command.setDestinationPosZ((short) 1); // 目标库位层 //// crnThread.write(command); // // // 2.出库 源和目标都发 //// CrnCommand command = new CrnCommand(); //// command.setCrnNo(1); // 堆垛机编号 //// command.setTaskNo((short) 0); // 工作号 //// command.setAckFinish((short) 0); // 任务完成确认位 //// command.setTaskMode(CrnTaskModeType.PAKOUT); // 任务模式 //// command.setSourcePosX((short) 2); // 源库位排 //// command.setSourcePosY((short) 4); // 源库位列 //// command.setSourcePosZ((short) 3); // 源库位层 //// command.setDestinationPosX((short) 1); // 目标库位排 //// command.setDestinationPosY((short) 0); // 目标库位列 //// command.setDestinationPosZ((short) 1); // 目标库位层 //// crnThread.write(command); // // //// // 3.库位移转 源和目标都发 pass //// CrnCommand command = new CrnCommand(); //// command.setCrnNo(slave.getId()); // 堆垛机编号 //// command.setTaskNo((short) 0); // 工作号 //// command.setAckFinish((short) 0); // 任务完成确认位 //// command.setTaskMode(CrnTaskModeType.LOC_MOVE); // 任务模式: 库位移转 //// command.setSourcePosX((short)2); // 源库位排 //// command.setSourcePosY((short)2); // 源库位列 //// command.setSourcePosZ((short)3); // 源库位层 //// command.setDestinationPosX((short)2); // 目标库位排 //// command.setDestinationPosY((short)4); // 目标库位列 //// command.setDestinationPosZ((short)4); // 目标库位层 //// crnThread.write(command); // // // 4.站位移转 源和目标都发 //// CrnCommand command = new CrnCommand(); //// command.setCrnNo(slave.getId()); // 堆垛机编号 //// command.setTaskNo((short) 0); // 工作号 //// command.setAckFinish((short) 0); // 任务完成确认位 //// command.setTaskMode(CrnTaskModeType.SITE_MOVE); // 任务模式: 库位移转 //// command.setSourcePosX((short)1); // 源库位排 //// command.setSourcePosY((short)0); // 源库位列 //// command.setSourcePosZ((short)1); // 源库位层 //// command.setDestinationPosX((short)2); // 目标库位排 //// command.setDestinationPosY((short)0); // 目标库位列 //// command.setDestinationPosZ((short)1); // 目标库位层 //// crnThread.write(command); // //// // 5.回原点 不用发 pass //// CrnCommand command = new CrnCommand(); //// command.setCrnNo(1); // 堆垛机编号 //// command.setTaskNo((short) 0); // 工作号 //// command.setAckFinish((short) 0); // 任务完成确认位 //// command.setTaskMode(CrnTaskModeType.GO_ORIGIN); // 任务模式 //// command.setSourcePosX((short) 0); // 源库位排 //// command.setSourcePosY((short) 0); // 源库位列 //// command.setSourcePosZ((short) 0); // 源库位层 //// command.setDestinationPosX((short) 0); // 目标库位排 //// command.setDestinationPosY((short) 0); // 目标库位列 //// command.setDestinationPosZ((short) 0); // 目标库位层 //// crnThread.write(command); // // // // 只有出现指定异常才进行复位 //// if (crnThread.crnProtocol.getCrnError2().leftTakeNoneErr //// || crnThread.crnProtocol.getCrnError2().rightTakeNoneErr //// || crnThread.crnProtocol.getCrnError2().leftPutLoadErr //// || crnThread.crnProtocol.getCrnError2().rightPutLoadErr) { //// CrnCommand command = new CrnCommand(); //// command.setCrnNo(1); // 堆垛机编号 //// command.setAckFinish((short) 1); // 任务完成确认位 //// command.setTaskMode(CrnTaskModeType.NONE); // 任务模式 //// Thread.sleep(3000L); //// crnThread.write(command); //// } // // } // // @Override // public void setResetFlagTwo(boolean flag) { // // } //}