package com.zy.core.thread; import HslCommunication.Core.Types.OperateResult; import HslCommunication.Core.Types.OperateResultExOne; import HslCommunication.Profinet.Siemens.SiemensPLCS; import HslCommunication.Profinet.Siemens.SiemensS7Net; import com.alibaba.fastjson.JSON; import com.core.common.Cools; import com.core.common.DateUtils; import com.core.common.SpringUtils; import com.zy.asrs.entity.BasRgv; import com.zy.asrs.entity.BasRgvOpt; import com.zy.asrs.service.BasRgvOptService; import com.zy.asrs.service.BasRgvService; import com.zy.asrs.utils.RouteUtils; import com.zy.core.ThreadHandler; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.OutputQueue; import com.zy.core.cache.RgvStatusCache; import com.zy.core.cache.TaskProtocolCache; import com.zy.core.enums.RgvModeType; import com.zy.core.enums.RgvStatusType; import com.zy.core.enums.RgvTaskModeType; import com.zy.core.enums.SlaveType; import com.zy.core.model.RgvSlave; import com.zy.core.model.Task; import com.zy.core.model.command.RgvCommand; import com.zy.core.model.protocol.RgvProtocol; import com.zy.core.model.protocol.TaskProtocol; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.text.MessageFormat; import java.util.Date; import java.util.List; import java.util.concurrent.ConcurrentHashMap; /** * RGV线程 * Created by vincent on 2022/11/29 */ @Data @Slf4j public class RgvThread implements Runnable, ThreadHandler { private SiemensS7Net siemensNet; private RgvSlave slave; // private RgvProtocol rgvProtocol; private TaskProtocolCache taskProtocolCache = new TaskProtocolCache(); /** * 工位1复位信号 */ private boolean resetFlag1 = false; /** * 工位2复位信号 */ private boolean resetFlag2 = false; public RgvThread(RgvSlave slave) { this.slave = slave; } @Override @SuppressWarnings("InfiniteLoopStatement") public void run() { boolean connect = this.connect(); if (connect){ // 启动读数据线程 new Thread(this::readStatusRgv).start(); // 启动任务下发线程 new Thread(this::taskTakeIssued).start(); new Thread(this::taskPutIssued).start(); new Thread(this::taskWalkIssued).start(); } } private void readStatusRgv(){ while (true) { try { Thread.sleep(100); readStatus(); } catch (Exception e) { log.error("RGV数据读取线程异常!!!"+e.getMessage()); initRgv(); // e.printStackTrace(); } } } /** * 任务下发 */ private void taskTakeIssued() { while (true) { try { // 休眠 1 秒 Thread.sleep(100); if (!deviceDetection()){ continue; } RgvProtocol rgvProtocol = RgvStatusCache.getRgvStatus(slave.getId()); if (rgvProtocol == null) { initRgv(); rgvProtocol = RgvStatusCache.getRgvStatus(slave.getId()); } if (rgvProtocol.getAvoid() == 0 || !rgvProtocol.getLoaded().equals((short) 0)) { continue; } List allTakeTaskProtocol = taskProtocolCache.getAllTakeTaskProtocol(); for(TaskProtocol taskProtocol: allTakeTaskProtocol){ if (taskProtocol.getTaskStatus() == 1){//准备下发 TaskProtocol issued = new TaskProtocol(taskProtocol); write(issued); taskProtocol.setIsRunning(taskProtocol.getIsRunning() +1); taskProtocolCache.updateTaskProtocol(taskProtocol); break; } } } catch (Exception e) { log.error("RGV取货任务下发线程异常!!!"+e.getMessage()); // e.printStackTrace(); } } } public boolean deviceDetection(){ RgvProtocol rgvProtocol = RgvStatusCache.getRgvStatus(slave.getId()); if (rgvProtocol == null) { return false; } if (!rgvProtocol.getModeType().equals(RgvModeType.AUTO) || rgvProtocol.getRgvPos().equals(0L) || !rgvProtocol.getStatusType().equals(RgvStatusType.IDLE)) { return false; } RgvProtocol rgvProtocolOther = RgvStatusCache.getRgvStatus(slave.getOtherId()); if (rgvProtocolOther == null) { return false; } if (rgvProtocolOther.statusEnable){ if (!rgvProtocolOther.getModeType().equals(RgvModeType.AUTO) || rgvProtocolOther.getRgvPos().equals(0L)) { return false; } } return true; } /** * 任务下发 */ private void taskPutIssued() { while (true) { try { // 休眠 1 秒 Thread.sleep(100); } catch (Exception e) { log.error("RGV放货任务下发线程异常!!!"+e.getMessage()); // e.printStackTrace(); } } } /** * 任务下发 */ private void taskWalkIssued() { while (true) { try { // 休眠 1 秒 Thread.sleep(100); } catch (Exception e) { log.error("RGV行走任务下发线程异常!!!"+e.getMessage()); // e.printStackTrace(); } } } /** * 初始化RGV状态 */ private void initRgv() { RgvProtocol rgvProtocol = RgvStatusCache.getRgvStatus(slave.getId()); if (rgvProtocol == null) { rgvProtocol = new RgvProtocol(); rgvProtocol.setRgvNo(slave.getId()); } rgvProtocol.setMode((short) -1); rgvProtocol.setStatus((short)-1); rgvProtocol.setWalkPos((short)0); rgvProtocol.setRgvPos(0L); rgvProtocol.setAlarm((short)0); rgvProtocol.setxSpeed((short) 0); rgvProtocol.setxDistance((short) 0); rgvProtocol.setxDuration((short) 0); BasRgvService basRgvService = SpringUtils.getBean(BasRgvService.class); BasRgv rgv = basRgvService.selectById(slave.getId()); if (!Cools.isEmpty(rgv)){ rgvProtocol.setStatusEnable(rgv.getStatus() == 1); } else { rgvProtocol.setStatusEnable(false); } RgvStatusCache.updateRgvStatus(rgvProtocol); } @Override public boolean connect() { boolean result = false; siemensNet = new SiemensS7Net(SiemensPLCS.S1200, slave.getIp()); siemensNet.setRack(slave.getRack().byteValue()); siemensNet.setSlot(slave.getSlot().byteValue()); OperateResult connect = siemensNet.ConnectServer(); if(connect.IsSuccess){ result = true; OutputQueue.RGV.offer(MessageFormat.format( "【{0}】RGV 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("RGV plc连接成功 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()); } else { OutputQueue.RGV.offer(MessageFormat.format("【{0}】RGV 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("RGV plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()); initRgv(); } // siemensNet.ConnectClose(); return result; } /** * 读取状态 */ private void readStatus(){ try { OperateResultExOne result = siemensNet.Read("DB101.0", (short) 34); if (result.IsSuccess) { // 构建设备状态对象 RgvProtocol rgvProtocol = RgvStatusCache.getRgvStatus(slave.getId()); if (rgvProtocol == null) { rgvProtocol = new RgvProtocol(); rgvProtocol.setRgvNo(slave.getId()); } rgvProtocol.setMode(siemensNet.getByteTransform().TransInt16(result.Content, 0)); rgvProtocol.setStatus(siemensNet.getByteTransform().TransInt16(result.Content, 2)); rgvProtocol.setRgvPos(siemensNet.getByteTransform().TransUInt32(result.Content, 10)); rgvProtocol.setAlarm(siemensNet.getByteTransform().TransInt16(result.Content, 20)); // rgvProtocol.setxSpeed(siemensNet.getByteTransform().TransInt16(result.Content, 28)); // rgvProtocol.setxDistance(siemensNet.getByteTransform().TransInt16(result.Content, 40)); // rgvProtocol.setxDuration(siemensNet.getByteTransform().TransInt16(result.Content, 48)); OutputQueue.RGV.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId())); // // 工位1复位信号 // if (rgvProtocol.getStatusType().equals(RgvStatusType.WAITING) // || rgvProtocol.getStatusType().equals(RgvStatusType.FETCHWAITING)) { // if (resetFlag1) { // RgvCommand rgvCommand = new RgvCommand(); // rgvCommand.setAckFinish1((short)1); // if (write(rgvCommand)) { // resetFlag1 = false; // } // } // } try { // 根据实时信息更新数据库 BasRgvService basRgvService = SpringUtils.getBean(BasRgvService.class); BasRgv basRgv = basRgvService.selectById(slave.getId()); if (!Cools.isEmpty(basRgv)){ rgvProtocol.setStatusEnable(basRgv.getStatus() == 1); } else { rgvProtocol.setStatusEnable(false); } // BasRgv basRgv = new BasRgv(); basRgv.setRgvNo(slave.getId()); basRgv.setRgvSts((int)rgvProtocol.getMode()); if (!basRgvService.updateById(rgvProtocol.toSqlModel(basRgv))){ log.error("RGV plc数据库更新失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()); } } catch (Exception ignore){ } // 更新缓存 RgvStatusCache.updateRgvStatus(rgvProtocol); } else { initRgv(); // OutputQueue.RGV.offer(MessageFormat.format("【{0}】读取RGV 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("读取RGV plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()); } } catch (Exception e) { // e.printStackTrace(); // OutputQueue.RGV.offer(MessageFormat.format("【{0}】读取RGV plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); log.error("读取RGV plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); initRgv(); } } /** * 写入数据 */ private boolean write(TaskProtocol taskProtocol) throws InterruptedException { if (null == taskProtocol) { log.error("RGV写入命令为空"); return false; } // convertRow(command); // taskProtocol.setRgvNo(slave.getId()); Long[] array = new Long[11]; // array[0] = taskProtocol.getAckFinish1(); array[1] = taskProtocol.getTaskNo(); // array[2] = taskProtocol.getTaskMode(); // array[4] = command.getDestinationStaNo(); // array[10] = taskProtocol.getCommand(); OperateResult result = siemensNet.Write("DB100.0", taskProtocol.getTaskNo()); // if (taskProtocol.getAckFinish1() == 0) { // short commandFinish = 3; //工位1、2任务同时写入 // Thread.sleep(100L); // result = siemensNet.Write("DB100.20", commandFinish); // } try { // 日志记录 BasRgvOptService bean = SpringUtils.getBean(BasRgvOptService.class); BasRgvOpt basRgvOpt = new BasRgvOpt( taskProtocol.getTaskNo().intValue(), taskProtocol.getTaskNo().intValue(), slave.getId(), new Date(), String.valueOf(taskProtocol.getTaskStatus()), null, null, null, result.IsSuccess? 1 : 0, null, new Date(), null ); bean.insert(basRgvOpt); } catch (Exception ignore) {} if (result != null && result.IsSuccess) { Thread.sleep(200); this.readStatus(); log.info("RGV 命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(taskProtocol)); OutputQueue.RGV.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(taskProtocol))); return true; } else { OutputQueue.RGV.offer(MessageFormat.format("【{0}】写入RGV plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); log.error("写入RGV plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); return false; } } @Override public void close() { siemensNet.ConnectClose(); } }