New file |
| | |
| | | package com.zy.asrs.wcs.rcs.thread.impl; |
| | | |
| | | 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.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.zy.asrs.framework.common.DateUtils; |
| | | import com.zy.asrs.framework.common.SpringUtils; |
| | | import com.zy.asrs.framework.exception.CoolException; |
| | | import com.zy.asrs.wcs.common.ExecuteSupport; |
| | | import com.zy.asrs.wcs.core.entity.BasLift; |
| | | import com.zy.asrs.wcs.core.model.command.LiftCommand; |
| | | import com.zy.asrs.wcs.core.model.enums.LiftCommandModeType; |
| | | import com.zy.asrs.wcs.core.service.BasLiftService; |
| | | import com.zy.asrs.wcs.core.utils.RedisUtil; |
| | | import com.zy.asrs.wcs.core.utils.Utils; |
| | | import com.zy.asrs.wcs.rcs.News; |
| | | import com.zy.asrs.wcs.rcs.cache.OutputQueue; |
| | | import com.zy.asrs.wcs.rcs.entity.Device; |
| | | import com.zy.asrs.wcs.rcs.entity.DeviceDataLog; |
| | | import com.zy.asrs.wcs.rcs.model.enums.LiftProtocolStatusType; |
| | | import com.zy.asrs.wcs.rcs.model.enums.SlaveType; |
| | | import com.zy.asrs.wcs.rcs.model.protocol.LiftProtocol; |
| | | import com.zy.asrs.wcs.rcs.service.DeviceDataLogService; |
| | | import com.zy.asrs.wcs.rcs.thread.LiftThread; |
| | | import lombok.Data; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.text.MessageFormat; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | |
| | | @Slf4j |
| | | @SuppressWarnings("all") |
| | | public class NyLiftThread implements LiftThread { |
| | | |
| | | private Device device; |
| | | private RedisUtil redisUtil; |
| | | private LiftProtocol liftProtocol; |
| | | private SiemensS7Net siemensS7Net; |
| | | private List<LiftStaProtocol> liftStaProtocols = new ArrayList<>(); |
| | | private List<Sta> staList = new ArrayList<>(); |
| | | |
| | | public NyLiftThread(Device device, RedisUtil redisUtil) { |
| | | this.device = device; |
| | | this.redisUtil = redisUtil; |
| | | |
| | | //初始化站点 |
| | | BasLiftService basLiftService = SpringUtils.getBean(BasLiftService.class); |
| | | BasLift basLift = basLiftService.getOne(new LambdaQueryWrapper<BasLift>() |
| | | .eq(BasLift::getDeviceId, device.getId())); |
| | | List<Sta> staList = JSON.parseArray(basLift.getSta(), Sta.class); |
| | | this.staList = staList; |
| | | for (Sta sta : staList) { |
| | | LiftStaProtocol liftStaProtocol = new LiftStaProtocol(); |
| | | liftStaProtocol.setStaNo(sta.getStaNo());//站点号 |
| | | liftStaProtocol.setLev(sta.getLev());//站点楼层 |
| | | String locNo = Utils.getLocNo(sta.getRow(), sta.getBay(), sta.getLev()); |
| | | liftStaProtocol.setLocNo(locNo);//站点库位号 |
| | | liftStaProtocol.setLiftNo(basLift.getLiftNo());//提升机号 |
| | | liftStaProtocols.add(liftStaProtocol); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void run() { |
| | | News.info("{}号提升机线程启动", device.getDeviceNo()); |
| | | this.connect(); |
| | | while (true) { |
| | | try { |
| | | read(); |
| | | Thread.sleep(500); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void read() { |
| | | try { |
| | | readStatus(); |
| | | |
| | | //提升机处于运行状态,将标记置为false |
| | | if (liftProtocol.getRun()) { |
| | | liftProtocol.setPakMk(false); |
| | | } |
| | | } catch (Exception e) { |
| | | OutputQueue.LIFT.offer(MessageFormat.format("【{0}】读取提升机状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), device.getId(), device.getIp(), device.getPort())); |
| | | } |
| | | } |
| | | |
| | | private void readStatus() { |
| | | try { |
| | | //获取提升机数据 |
| | | OperateResultExOne<byte[]> result1 = siemensS7Net.Read("DB82.4.0", (short) 10); |
| | | if (result1.IsSuccess) { |
| | | if (null == liftProtocol) { |
| | | liftProtocol = new LiftProtocol(); |
| | | liftProtocol.setLiftNo(Integer.valueOf(device.getDeviceNo())); |
| | | liftProtocol.setProtocolStatus(LiftProtocolStatusType.IDLE); |
| | | liftProtocol.setDevice(device); |
| | | |
| | | InnerLiftExtend innerLiftExtend = new InnerLiftExtend(); |
| | | liftProtocol.setExtend(innerLiftExtend); |
| | | } |
| | | |
| | | //----------读取提升机状态----------- |
| | | //读取4.0-4.7数据 |
| | | boolean[] status1 = siemensS7Net.getByteTransform().TransBool(result1.Content, 0, 1); |
| | | //读取5.0-5.7数据 |
| | | boolean[] status2 = siemensS7Net.getByteTransform().TransBool(result1.Content, 1, 1); |
| | | //模式 |
| | | liftProtocol.setModel(status1[0]); |
| | | //忙闲 |
| | | liftProtocol.setRun(!status1[1]); |
| | | //前超限 |
| | | liftProtocol.setFrontOverrun(status1[4]); |
| | | //后超限 |
| | | liftProtocol.setBackOverrun(status1[5]); |
| | | //左超限 |
| | | liftProtocol.setLeftOverrun(status1[6]); |
| | | //右超限 |
| | | liftProtocol.setRightOverrun(status1[7]); |
| | | //超高 |
| | | liftProtocol.setOverHeight(status2[0]); |
| | | //超重 |
| | | liftProtocol.setOverWeight(status2[1]); |
| | | //有托盘 |
| | | liftProtocol.setHasTray(status2[5]); |
| | | //有小车 |
| | | liftProtocol.setHasCar(status2[6]); |
| | | //设备故障 |
| | | liftProtocol.setErrorCode(String.valueOf(status2[7])); |
| | | //目的地址 |
| | | liftProtocol.setDistAddress(siemensS7Net.getByteTransform().TransInt16(result1.Content, 4)); |
| | | //已完成任务号 |
| | | liftProtocol.setCompleteTaskNo(String.valueOf(siemensS7Net.getByteTransform().TransInt16(result1.Content, 6))); |
| | | //当前楼层 |
| | | short lev = siemensS7Net.getByteTransform().TransInt16(result1.Content, 8); |
| | | liftProtocol.setLev((int) lev); |
| | | |
| | | //************补充扩展字段************* |
| | | InnerLiftExtend liftExtend = JSON.parseObject(JSON.toJSONString(liftProtocol.getExtend()), InnerLiftExtend.class); |
| | | //任务号 |
| | | liftExtend.setLiftTaskNo(String.valueOf(siemensS7Net.getByteTransform().TransInt16(result1.Content, 2))); |
| | | liftProtocol.setExtend(liftExtend); |
| | | |
| | | |
| | | }else { |
| | | OutputQueue.LIFT.offer(MessageFormat.format("【{0}】{1}读取提升机状态信息失败", DateUtils.convert(new Date()), device.getId())); |
| | | throw new CoolException(MessageFormat.format( "读取提升机状态信息失败 ===>> [id:{0}] [ip:{1}] [port:{2}]", device.getId(), device.getIp(), device.getPort())); |
| | | } |
| | | Thread.sleep(200); |
| | | |
| | | //获取提升机站点数据 |
| | | OperateResultExOne<byte[]> result2 = siemensS7Net.Read("DB82.14.0", (short) (10 * liftStaProtocols.size())); |
| | | if (result1.IsSuccess) { |
| | | for (int i = 0; i < this.staList.size(); i++) { |
| | | LiftStaProtocol liftStaProtocol = liftStaProtocols.get(i); |
| | | int i1 = 0 + (i * 10); |
| | | int i2 = 1 + (i * 10); |
| | | //读取x4.0-x4.7数据 |
| | | boolean[] status1 = siemensS7Net.getByteTransform().TransBool(result2.Content, i1, 1); |
| | | //读取x5.0-x5.7数据 |
| | | boolean[] status2 = siemensS7Net.getByteTransform().TransBool(result2.Content, i2, 1); |
| | | //模式 |
| | | liftStaProtocol.setModel(status1[0]); |
| | | //忙闲 |
| | | liftStaProtocol.setBusy(!status1[1]); |
| | | //有托盘 |
| | | liftStaProtocol.setHasTray(status1[2]); |
| | | //前超限 |
| | | liftStaProtocol.setFrontOverrun(status1[4]); |
| | | //后超限 |
| | | liftStaProtocol.setBackOverrun(status1[5]); |
| | | //左超限 |
| | | liftStaProtocol.setLeftOverrun(status1[6]); |
| | | //右超限 |
| | | liftStaProtocol.setRightOverrun(status1[7]); |
| | | //超高 |
| | | liftStaProtocol.setOverHeight(status2[0]); |
| | | //超重 |
| | | liftStaProtocol.setOverWeight(status2[1]); |
| | | //有小车 |
| | | liftStaProtocol.setHasCar(status2[6]); |
| | | //设备故障 |
| | | liftStaProtocol.setDeviceError(status2[7]); |
| | | //任务号 |
| | | liftStaProtocol.setTaskNo(siemensS7Net.getByteTransform().TransInt16(result2.Content, 2)); |
| | | //已完成任务号 |
| | | liftStaProtocol.setCompleteTaskNo(siemensS7Net.getByteTransform().TransInt16(result2.Content, 6)); |
| | | } |
| | | } |
| | | |
| | | if (System.currentTimeMillis() - liftProtocol.getDeviceDataLog() > 1000 * 5) { |
| | | //采集时间超过5s,保存一次数据记录 |
| | | //保存数据记录 |
| | | DeviceDataLogService deviceDataLogService = SpringUtils.getBean(DeviceDataLogService.class); |
| | | DeviceDataLog deviceDataLog = new DeviceDataLog(); |
| | | deviceDataLog.setOriginData(Base64.getEncoder().encodeToString(result1.Content)); |
| | | deviceDataLog.setWcsData(JSON.toJSONString(liftProtocol)); |
| | | deviceDataLog.setType("lift"); |
| | | deviceDataLog.setDeviceNo(String.valueOf(liftProtocol.getLiftNo())); |
| | | deviceDataLog.setCreateTime(new Date()); |
| | | deviceDataLog.setHostId(device.getHostId()); |
| | | deviceDataLogService.save(deviceDataLog); |
| | | |
| | | //更新采集时间 |
| | | liftProtocol.setDeviceDataLog(System.currentTimeMillis()); |
| | | } |
| | | |
| | | } catch (Exception e) { |
| | | OutputQueue.LIFT.offer(MessageFormat.format("【{0}】读取提升机状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), device.getId(), device.getIp(), device.getPort())); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public LiftProtocol getStatus() { |
| | | return this.liftProtocol.clone(); |
| | | } |
| | | |
| | | @Override |
| | | public Device getDevice() { |
| | | return this.device; |
| | | } |
| | | |
| | | @Override |
| | | public boolean move(LiftCommand command) { |
| | | return write(command); |
| | | } |
| | | |
| | | @Override |
| | | public boolean palletInOut(LiftCommand command) { |
| | | return write(command); |
| | | } |
| | | |
| | | private boolean write(LiftCommand command) { |
| | | if (null == command) { |
| | | News.error("提升机写入命令为空"); |
| | | return false; |
| | | } |
| | | |
| | | List<Short> shorts = JSON.parseArray(command.getBody(), Short.class); |
| | | short[] array = new short[shorts.size()];//获取命令报文 |
| | | for (int i = 0; i < shorts.size(); i++) { |
| | | array[i] = shorts.get(i); |
| | | } |
| | | |
| | | OperateResult result = siemensS7Net.Write("DB83.0", array); |
| | | if (result != null && result.IsSuccess) { |
| | | liftProtocol.setSendTime(System.currentTimeMillis());//指令下发时间 |
| | | News.info("提升机命令下发[id:{}] >>>>> {}", device.getId(), JSON.toJSON(command)); |
| | | OutputQueue.LIFT.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), device.getId(), JSON.toJSON(command))); |
| | | return true; |
| | | } else { |
| | | OutputQueue.LIFT.offer(MessageFormat.format("【{0}】写入提升机plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}],次数:{}", DateUtils.convert(new Date()), device.getId(), device.getIp(), device.getPort())); |
| | | News.error("写入提升机plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", device.getId(), device.getIp(), device.getPort()); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public boolean lock(LiftCommand command) { |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public boolean unlock(LiftCommand command) { |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public boolean reset(LiftCommand command) { |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isIdle() { |
| | | return isIdle(null); |
| | | } |
| | | |
| | | @Override |
| | | public boolean isIdle(ExecuteSupport support) { |
| | | if (null != support) { |
| | | if (!support.judgement()) { |
| | | return false; |
| | | } |
| | | } |
| | | // 判断提升机是否自动、就绪、空闲 |
| | | if (this.liftProtocol.getModel() |
| | | && !this.liftProtocol.getRun() |
| | | && this.liftProtocol.getReady() |
| | | && this.liftProtocol.getPakMk() |
| | | && this.liftProtocol.getErrorCode().equals("0") |
| | | && this.liftProtocol.getProtocolStatus().equals(LiftProtocolStatusType.IDLE) |
| | | ) { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public LiftCommand getMoveCommand(Integer taskNo, Integer sourceLev, Integer targetLev, Integer mode) { |
| | | /** |
| | | * 任务类型 |
| | | * 1=移托盘;升降机将源站台托盘移到目标站台 |
| | | * 2=移小车,升降机移到目标层,等待 |
| | | */ |
| | | short taskMode = 2; |
| | | if (mode == null) { |
| | | taskMode = mode.shortValue(); |
| | | } |
| | | |
| | | // 开始任务 |
| | | short[] array = new short[4]; |
| | | //任务类型 |
| | | array[0] = taskMode; |
| | | //源站台编号 |
| | | array[1] = sourceLev.shortValue(); |
| | | //目标站台编号 |
| | | array[2] = targetLev.shortValue(); |
| | | //任务号 |
| | | array[3] = taskNo.shortValue(); |
| | | |
| | | LiftCommand command = new LiftCommand(); |
| | | command.setLiftNo(Integer.valueOf(this.device.getDeviceNo())); |
| | | command.setBody(JSON.toJSONString(array)); |
| | | command.setMode(LiftCommandModeType.MOVE.id); |
| | | command.setOriginLev(sourceLev); |
| | | command.setTargetLev(targetLev); |
| | | return command; |
| | | } |
| | | |
| | | @Override |
| | | public LiftCommand getMoveWithShuttleCommand(Integer taskNo, Integer sourceLev, Integer targetLev, Integer mode) { |
| | | return getMoveCommand(taskNo, sourceLev, targetLev, 2); |
| | | } |
| | | |
| | | @Override |
| | | public LiftCommand getPalletInOutCommand(Integer taskNo, Integer sourceLev, Integer targetLev, Integer originSta, Integer targetSta, Integer mode) { |
| | | return getMoveCommand(taskNo, sourceLev, targetLev, 1); |
| | | } |
| | | |
| | | @Override |
| | | public LiftCommand getLockCommand(Integer taskNo, Boolean lock) { |
| | | LiftCommand command = new LiftCommand(); |
| | | return command; |
| | | } |
| | | |
| | | @Override |
| | | public LiftCommand getShuttleSignalCommand(Integer taskNo, Boolean signal) { |
| | | LiftCommand command = new LiftCommand(); |
| | | return command; |
| | | } |
| | | |
| | | @Override |
| | | public boolean connect() { |
| | | boolean result = false; |
| | | //-------------------------提升机连接方法------------------------// |
| | | siemensS7Net = new SiemensS7Net(SiemensPLCS.S1200, device.getIp()); |
| | | OperateResult connect = siemensS7Net.ConnectServer(); |
| | | if(connect.IsSuccess){ |
| | | result = true; |
| | | OutputQueue.LIFT.offer(MessageFormat.format( "【{0}】提升机plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), device.getId(), device.getIp(), device.getPort())); |
| | | log.info("提升机plc连接成功 ===>> [id:{}] [ip:{}] [port:{}] ", device.getId(), device.getIp(), device.getPort()); |
| | | } else { |
| | | OutputQueue.LIFT.offer(MessageFormat.format("【{0}】提升机plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), device.getId(), device.getIp(), device.getPort())); |
| | | log.error("提升机plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}] ", device.getId(), device.getIp(), device.getPort()); |
| | | } |
| | | siemensS7Net.ConnectClose(); |
| | | //-------------------------提升机连接方法------------------------// |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public void close() { |
| | | siemensS7Net.ConnectClose(); |
| | | } |
| | | |
| | | /** |
| | | * 扩展字段 |
| | | */ |
| | | @Data |
| | | private class InnerLiftExtend { |
| | | |
| | | /** |
| | | * 提升机内部工作号 |
| | | */ |
| | | private String liftTaskNo; |
| | | |
| | | } |
| | | |
| | | @Data |
| | | public class LiftStaProtocol { |
| | | |
| | | /** |
| | | * 站点号 |
| | | */ |
| | | private Integer staNo; |
| | | |
| | | /** |
| | | * 模式 |
| | | */ |
| | | private Boolean model; |
| | | |
| | | /** |
| | | * 忙闲 |
| | | */ |
| | | private Boolean busy; |
| | | |
| | | /** |
| | | * 前超限 |
| | | */ |
| | | private Boolean frontOverrun; |
| | | |
| | | /** |
| | | * 后超限 |
| | | */ |
| | | private Boolean backOverrun; |
| | | |
| | | /** |
| | | * 左超限 |
| | | */ |
| | | private Boolean leftOverrun; |
| | | |
| | | /** |
| | | * 右超限 |
| | | */ |
| | | private Boolean rightOverrun; |
| | | |
| | | /** |
| | | * 超高 |
| | | */ |
| | | private Boolean overHeight; |
| | | |
| | | /** |
| | | * 超重 |
| | | */ |
| | | private Boolean overWeight; |
| | | |
| | | /** |
| | | * 有托盘 |
| | | */ |
| | | private Boolean hasTray; |
| | | |
| | | /** |
| | | * 有小车 |
| | | */ |
| | | private Boolean hasCar; |
| | | |
| | | /** |
| | | * 设备故障 |
| | | */ |
| | | private Boolean deviceError; |
| | | |
| | | /** |
| | | * 当前执行任务号 |
| | | */ |
| | | private Short taskNo; |
| | | /** |
| | | * 已完成的任务号 |
| | | */ |
| | | private Short completeTaskNo; |
| | | |
| | | /** |
| | | * 层 |
| | | */ |
| | | private Integer lev; |
| | | |
| | | /** |
| | | * 站点库位号 |
| | | */ |
| | | private String locNo; |
| | | |
| | | /** |
| | | * 提升机号 |
| | | */ |
| | | private Integer liftNo; |
| | | |
| | | } |
| | | |
| | | @Data |
| | | public static class Sta { |
| | | |
| | | // 提升机站点号 |
| | | private Integer staNo; |
| | | |
| | | //输送站点排 |
| | | private Integer row; |
| | | |
| | | //输送站点列 |
| | | private Integer bay; |
| | | |
| | | // 层 |
| | | private Integer lev; |
| | | |
| | | } |
| | | |
| | | } |