package com.zy.core.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.mapper.EntityWrapper; import com.core.common.DateUtils; import com.core.common.SpringUtils; import com.zy.asrs.entity.BasLift; import com.zy.asrs.entity.DeviceDataLog; import com.zy.asrs.service.BasLiftService; import com.zy.asrs.service.DeviceDataLogService; import com.zy.asrs.utils.Utils; import com.zy.common.ExecuteSupport; import com.zy.common.utils.RedisUtil; import com.zy.core.News; import com.zy.core.action.ForkLiftAction; import com.zy.core.cache.OutputQueue; import com.zy.core.cache.SlaveConnection; import com.zy.core.enums.*; import com.zy.core.model.CommandResponse; import com.zy.core.model.ForkLiftSlave; import com.zy.core.model.command.ForkLiftCommand; import com.zy.core.model.protocol.ForkLiftProtocol; import com.zy.core.model.protocol.ForkLiftStaProtocol; import com.zy.core.thread.ForkLiftThread; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Base64; import java.util.Date; import java.util.List; @Slf4j @SuppressWarnings("all") public class LfdZyForkLiftSlaveThread implements ForkLiftThread { private Integer masterId; private ForkLiftSlave slave; private ForkLiftProtocol forkLiftProtocol; private RedisUtil redisUtil; private List forkLiftStaProtocols = new ArrayList<>(); private LfdZyForkLiftMasterThread masterThread; public LfdZyForkLiftSlaveThread(ForkLiftSlave slave, RedisUtil redisUtil, Integer masterId) { this.slave = slave; this.redisUtil = redisUtil; this.masterId = masterId; //初始化站点 for (ForkLiftSlave.Sta sta : this.slave.getSta()) { ForkLiftStaProtocol forkLiftStaProtocol = new ForkLiftStaProtocol(); forkLiftStaProtocol.setStaNo(sta.getStaNo());//站点号 forkLiftStaProtocol.setLev(sta.getLev());//站点楼层 String locNo = Utils.getLocNo(this.slave.getStaRow(), this.slave.getStaBay(), sta.getLev()); forkLiftStaProtocol.setLocNo(locNo);//站点库位号 forkLiftStaProtocol.setLiftNo(sta.getLiftNo());//提升机号 forkLiftStaProtocols.add(forkLiftStaProtocol); } } @Override public boolean connect() { boolean result = false; LfdZyForkLiftMasterThread masterThread = (LfdZyForkLiftMasterThread) SlaveConnection.get(SlaveType.ForkLiftMaster, masterId); if(masterThread != null) { result = true; this.masterThread = masterThread; } return result; } @Override public void close() { } @Override public void run() { News.info("{}号货叉提升机线程启动", slave.getId()); this.connect(); while (true) { try { if (this.masterThread == null) { this.connect(); continue; } read(); Thread.sleep(200); execute(); } catch (Exception e) { e.printStackTrace(); } } } private void execute() { ForkLiftAction forkLiftAction = SpringUtils.getBean(ForkLiftAction.class); if (forkLiftAction == null) { return; } Object object = redisUtil.get(RedisKeyType.FORK_LIFT_FLAG.key + slave.getId()); if (object == null) { return; } Integer taskNo = Integer.valueOf(String.valueOf(object)); if (taskNo != 0) { //存在任务需要执行 boolean result = forkLiftAction.executeWork(slave.getId(), taskNo); } } private void read() { try { readStatus(); //提升机处于运行状态,将标记置为true if (forkLiftProtocol.getProtocolStatusType().equals(ForkLiftProtocolStatusType.PICK_UP) || forkLiftProtocol.getProtocolStatusType().equals(ForkLiftProtocolStatusType.PUT_DOWN) || forkLiftProtocol.getProtocolStatusType().equals(ForkLiftProtocolStatusType.WAITING)) { forkLiftProtocol.setPakMk(true); } } catch (Exception e) { OutputQueue.FORKLIFT.offer(MessageFormat.format("【{0}】读取提升机状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); } } private void readStatus() { try { //获取提升机数据 OperateResultExOne result1 = this.masterThread.read(this.slave.getId(), "status"); if (result1 == null) { OutputQueue.FORKLIFT.offer(MessageFormat.format("【{0}】{1}读取货叉提升机状态信息失败", DateUtils.convert(new Date()), slave.getId())); } SiemensS7Net siemensS7Net = this.masterThread.getSiemensS7Net(); if (result1.IsSuccess) { if (null == forkLiftProtocol) { forkLiftProtocol = new ForkLiftProtocol(); forkLiftProtocol.setLiftNo(slave.getId()); forkLiftProtocol.setProtocolStatus(ForkLiftProtocolStatusType.NONE); InnerForkLiftExtend innerForkLiftExtend = new InnerForkLiftExtend(); } //----------读取提升机状态----------- //模式 forkLiftProtocol.setModel((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 0)); //PLC任务号 forkLiftProtocol.setWrkNo((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 2)); //任务状态 forkLiftProtocol.setProtocolStatus((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 4)); //任务模式 forkLiftProtocol.setTaskMode((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 6)); //取货数据 forkLiftProtocol.setPick((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 8)); //放货数据 forkLiftProtocol.setPut((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 10)); //出入库模式 forkLiftProtocol.setIOMode((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 12)); //故障码 forkLiftProtocol.setErrorCode((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 14)); //************补充扩展字段************* InnerForkLiftExtend forkLiftExtend = (InnerForkLiftExtend) forkLiftProtocol.getExtend(); forkLiftProtocol.setExtend(forkLiftExtend); }else { OutputQueue.FORKLIFT.offer(MessageFormat.format("【{0}】{1}读取货叉提升机状态信息失败", DateUtils.convert(new Date()), slave.getId())); } OperateResultExOne result2 = this.masterThread.read(this.slave.getId(), "staStatus"); if (result2.IsSuccess) { for (int i = 0; i < this.slave.getSta().size(); i++) { ForkLiftSlave.Sta sta = this.slave.getSta().get(i); if (forkLiftStaProtocols.isEmpty()) { continue; } ForkLiftStaProtocol forkLiftStaProtocol = forkLiftStaProtocols.get(i); boolean[] status1 = siemensS7Net.getByteTransform().TransBool(result2.Content, i * 2, 2); forkLiftStaProtocol.setHasTray(status1[0]); forkLiftStaProtocol.setHasCar(status1[1]); } } if (System.currentTimeMillis() - forkLiftProtocol.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(forkLiftProtocol)); deviceDataLog.setType("forkLift"); deviceDataLog.setDeviceNo(forkLiftProtocol.getLiftNo()); deviceDataLog.setCreateTime(new Date()); deviceDataLogService.insert(deviceDataLog); //保存数据记录 DeviceDataLog deviceDataLog2 = new DeviceDataLog(); deviceDataLog2.setOriginData(Base64.getEncoder().encodeToString(result2.Content)); deviceDataLog2.setWcsData(JSON.toJSONString(forkLiftStaProtocols)); deviceDataLog2.setType("forkLiftStaProtocols"); deviceDataLog2.setDeviceNo(forkLiftProtocol.getLiftNo()); deviceDataLog2.setCreateTime(new Date()); deviceDataLogService.insert(deviceDataLog2); //更新采集时间 forkLiftProtocol.setDeviceDataLog(System.currentTimeMillis()); } //将提升机状态保存至数据库 BasLiftService basLiftService = SpringUtils.getBean(BasLiftService.class); BasLift basLift = basLiftService.selectOne(new EntityWrapper() .eq("lift_no", slave.getId())); if (basLift == null) { basLift = new BasLift(); //提升机号 basLift.setLiftNo(forkLiftProtocol.getLiftNo()); basLift.setStatus(1); basLiftService.insert(basLift); } //任务号 basLift.setWrkNo(forkLiftProtocol.getTaskNo()); //修改时间 basLift.setUpdateTime(new Date()); //设备状态 basLift.setDeviceStatus(JSON.toJSONString(forkLiftProtocol)); if (basLiftService.updateById(basLift)) { OutputQueue.FORKLIFT.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), forkLiftProtocol.getLiftNo())); } } catch (Exception e) { OutputQueue.FORKLIFT.offer(MessageFormat.format("【{0}】读取货叉提升机状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); } } @Override public ForkLiftProtocol getStatus(boolean clone) { if (this.forkLiftProtocol == null) { return null; } return clone ? this.forkLiftProtocol.clone() : this.forkLiftProtocol; } @Override public List getForkLiftStaProtocols() { return this.forkLiftStaProtocols; } @Override public ForkLiftProtocol getStatus() { return getStatus(true); } @Override public CommandResponse pickAndPut(ForkLiftCommand command) { CommandResponse response = new CommandResponse(false); short[] array = new short[4]; array[0] = command.getTaskNo();//任务号 array[1] = command.getMode();//任务模式 array[2] = command.getPick();//取货数据 array[3] = command.getPut();//放货数据 OperateResult result = this.masterThread.write(this.slave.getId(), "write", array); if (result.IsSuccess) { OperateResult result2 = this.masterThread.write(this.slave.getId(), "writeConfirm", command.getConfirm()); if (result2.IsSuccess) { response.setResult(true); } } return response; } @Override public CommandResponse shuttleSwitch(ForkLiftCommand command) { CommandResponse response = new CommandResponse(false); short[] array = new short[4]; array[0] = command.getTaskNo();//任务号 array[1] = command.getMode();//任务模式 array[2] = command.getPick();//取货数据 array[3] = command.getPut();//放货数据 OperateResult result = this.masterThread.write(this.slave.getId(), "write", array); if (result.IsSuccess) { OperateResult result2 = this.masterThread.write(this.slave.getId(), "writeConfirm", command.getConfirm()); if (result2.IsSuccess) { response.setResult(true); } } return response; } @Override public CommandResponse reset() { CommandResponse response = new CommandResponse(false); OperateResult result = this.masterThread.write(this.slave.getId(), "confirm", (short) 1); if (result.IsSuccess) { News.info("货叉提升机确认命令下发成功,提升机号={}", forkLiftProtocol.getLiftNo()); response.setResult(true); } return response; } @Override public boolean isIdle() { if (this.forkLiftProtocol.getTaskNo() == null || this.forkLiftProtocol.getProtocolStatus() == null || this.forkLiftProtocol.getModel() == null || this.forkLiftProtocol.getErrorCode() == null ) { return false; } boolean res = this.forkLiftProtocol.getProtocolStatus() == ForkLiftProtocolStatusType.IDLE.id && this.forkLiftProtocol.getWrkNo() == 0 && this.forkLiftProtocol.getTaskNo() == 0 && this.forkLiftProtocol.getModel() == 2 && this.forkLiftProtocol.getErrorCode() == 0 ; return res; } @Override public boolean isDeviceIdle() { return isDeviceIdle(null); } @Override public boolean isDeviceIdle(ExecuteSupport support) { if (null != support) { Boolean judgement = support.judgement(); if (judgement != null && !judgement) { return true; } } if (this.forkLiftProtocol.getTaskNo() == null || this.forkLiftProtocol.getProtocolStatus() == null || this.forkLiftProtocol.getModel() == null || this.forkLiftProtocol.getErrorCode() == null ) { return false; } boolean res = this.forkLiftProtocol.getProtocolStatus() == ForkLiftProtocolStatusType.IDLE.id && this.forkLiftProtocol.getWrkNo() == 0 && this.forkLiftProtocol.getModel() == 2 && this.forkLiftProtocol.getErrorCode() == 0 ; return res; } @Override public boolean setProtocolStatus(ForkLiftProtocolStatusType status) { return false; } @Override public boolean setSyncTaskNo(Integer taskNo) { this.forkLiftProtocol.setSyncTaskNo(taskNo); return true; } @Override public boolean switchIOMode(ForkLiftIoModeType type) { OperateResult result = this.masterThread.write(this.slave.getId(), "switchIOMode", type.id.shortValue()); if (result.IsSuccess) { return true; } return false; } @Override public int generateDeviceTaskNo(int taskNo, ForkLiftTaskModeType type) { return taskNo; } @Override public List getPickAndPutCommand(Integer taskNo, Integer pick, Integer put) { Integer realPick = pick % 1000; Integer realPut = put % 1000; List commands = new ArrayList<>(); ForkLiftCommand command = new ForkLiftCommand(); command.setLiftNo(slave.getId()); command.setTaskNo(taskNo.shortValue()); command.setMode(ForkLiftTaskModeType.PICK_PUT.id.shortValue()); command.setPick(realPick.shortValue()); command.setPut(realPut.shortValue()); command.setConfirm((short) 1); commands.add(command); return commands; } @Override public List getShuttleSwitchCommand(Integer taskNo, Integer pick, Integer put) { Integer realPick = pick % 1000; Integer realPut = put % 1000; List commands = new ArrayList<>(); ForkLiftCommand command = new ForkLiftCommand(); command.setLiftNo(slave.getId()); command.setTaskNo(taskNo.shortValue()); command.setMode(ForkLiftTaskModeType.SHUTTLE_SWITCH.id.shortValue()); command.setPick(realPick.shortValue()); command.setPut(realPut.shortValue()); command.setConfirm((short) 1); commands.add(command); return commands; } /** * 扩展字段 */ @Data private class InnerForkLiftExtend { } }