package com.zy.core.thread.impl; 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.BasCrnp; import com.zy.asrs.entity.DeviceConfig; import com.zy.asrs.entity.DeviceDataLog; import com.zy.asrs.service.BasCrnpService; import com.zy.asrs.utils.Utils; import com.zy.common.utils.RedisUtil; import com.zy.core.News; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.OutputQueue; import com.zy.core.enums.CrnTaskModeType; import com.zy.core.enums.RedisKeyType; import com.zy.core.enums.SlaveType; import com.zy.core.model.CommandResponse; import com.zy.core.model.Task; import com.zy.core.model.command.CrnCommand; import com.zy.core.model.protocol.CrnProtocol; import com.zy.core.network.DeviceConnectPool; import com.zy.core.network.ZyCrnConnectDriver; import com.zy.core.network.entity.ZyCrnStatusEntity; import com.zy.core.thread.CrnThread; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.text.MessageFormat; import java.util.Date; /** * 堆垛机线程 */ @Data @Slf4j public class ZySiemensCrnThread implements Runnable, CrnThread { private DeviceConfig deviceConfig; private RedisUtil redisUtil; private ZyCrnConnectDriver zyCrnConnectDriver; private CrnProtocol crnProtocol; private boolean resetFlag = false; public ZySiemensCrnThread(DeviceConfig deviceConfig, RedisUtil redisUtil) { this.deviceConfig = deviceConfig; this.redisUtil = redisUtil; } @Override @SuppressWarnings("InfiniteLoopStatement") public void run() { this.connect(); this.initCrn(); while (true) { try { int step = 1; Task task = MessageQueue.poll(SlaveType.Crn, deviceConfig.getDeviceNo()); if (task != null) { step = task.getStep(); } switch (step) { // 读数据 case 1: readStatus(); break; case 2: sendCommand((CrnCommand) task.getData()); break; default: break; } Thread.sleep(200); } catch (Exception e) { e.printStackTrace(); } } } /** * 初始化堆垛机状态 */ private void initCrn() { if (null == crnProtocol) { crnProtocol = new CrnProtocol(); crnProtocol.setCrnNo(deviceConfig.getDeviceNo()); } crnProtocol.setMode(-1); crnProtocol.setTaskNo(0); crnProtocol.setStatus(-1); crnProtocol.setBay(0); crnProtocol.setLevel(0); crnProtocol.setForkPos(-1); crnProtocol.setLiftPos(-1); crnProtocol.setWalkPos(0); crnProtocol.setLoaded(0); crnProtocol.setAlarm(0); crnProtocol.setXSpeed(0); crnProtocol.setYSpeed(0); crnProtocol.setZSpeed(0); crnProtocol.setXDistance(0); crnProtocol.setYDistance(0); crnProtocol.setXDuration(0); crnProtocol.setYDuration(0); } @Override public boolean connect() { zyCrnConnectDriver = new ZyCrnConnectDriver(deviceConfig); new Thread(zyCrnConnectDriver).start(); DeviceConnectPool.put(SlaveType.Crn, deviceConfig.getDeviceNo(), zyCrnConnectDriver); return true; } /** * 读取状态 */ private void readStatus(){ ZyCrnStatusEntity crnStatus = zyCrnConnectDriver.getStatus(); if (crnStatus == null) { OutputQueue.CRN.offer(MessageFormat.format("【{0}】读取堆垛机plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), deviceConfig.getDeviceNo(), deviceConfig.getIp(), deviceConfig.getPort())); News.error("SiemensCrn"+" - 5"+" - 读取堆垛机plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}]", deviceConfig.getDeviceNo(), deviceConfig.getIp(), deviceConfig.getPort()); return; } crnProtocol.setMode(crnStatus.getMode()); crnProtocol.setTaskNo(crnStatus.getTaskNo()); crnProtocol.setStatus(crnStatus.getStatus()); crnProtocol.setBay(crnStatus.getBay()); crnProtocol.setLevel(crnStatus.getLevel()); crnProtocol.setForkPos(crnStatus.getForkPos()); crnProtocol.setLiftPos(crnStatus.getLiftPos()); crnProtocol.setWalkPos(crnStatus.getWalkPos()); crnProtocol.setLoaded(crnStatus.getLoaded()); crnProtocol.setAlarm(crnStatus.getAlarm()); crnProtocol.setTemp1(crnStatus.getTemp1()); crnProtocol.setTemp2(crnStatus.getTemp2()); crnProtocol.setTemp3(crnStatus.getTemp3()); crnProtocol.setTemp4(crnStatus.getTemp4()); crnProtocol.setXSpeed(crnStatus.getXSpeed()); crnProtocol.setYSpeed(crnStatus.getYSpeed()); crnProtocol.setZSpeed(crnStatus.getZSpeed()); crnProtocol.setXDistance(crnStatus.getXDistance()); crnProtocol.setYDistance(crnStatus.getYDistance()); crnProtocol.setXDuration(crnStatus.getXDuration()); crnProtocol.setYDuration(crnStatus.getYDuration()); OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), deviceConfig.getDeviceNo())); // // 复位信号 // if (!Cools.isEmpty(crnProtocol.getStatusType()) && crnProtocol.getStatusType().equals(CrnStatusType.WAITING)) { // if (resetFlag) { // if(crnProtocol.getTaskNo()==9999){ // backHpFlag = false; // } // CrnCommand crnCommand = new CrnCommand(); // crnCommand.setAckFinish((short)1); // if (write(crnCommand)) { // resetFlag = false; // } // } // } if (crnProtocol.getAlarm() > 0) { crnProtocol.setLastCommandTime(-1L); } if (crnProtocol.getAlarm() == 0 && crnProtocol.getLastCommandTime() == -1) { crnProtocol.setLastCommandTime(System.currentTimeMillis()); } if (System.currentTimeMillis() - crnProtocol.getDeviceDataLog() > 200) { //保存数据记录 DeviceDataLog deviceDataLog = new DeviceDataLog(); deviceDataLog.setOriginData(JSON.toJSONString(crnStatus)); deviceDataLog.setWcsData(JSON.toJSONString(crnProtocol)); deviceDataLog.setType(String.valueOf(SlaveType.Crn)); deviceDataLog.setDeviceNo(crnProtocol.getCrnNo()); deviceDataLog.setCreateTime(new Date()); redisUtil.set(RedisKeyType.DEVICE_LOG_KEY.key + System.currentTimeMillis(), deviceDataLog, 60 * 60 * 24); //更新采集时间 crnProtocol.setDeviceDataLog(System.currentTimeMillis()); } BasCrnpService basCrnpService = SpringUtils.getBean(BasCrnpService.class); if (basCrnpService != null) { BasCrnp basCrnp = basCrnpService.selectOne(new EntityWrapper().eq("crn_no", deviceConfig.getDeviceNo())); if(basCrnp == null) { basCrnp = new BasCrnp(); basCrnp.setCrnNo(deviceConfig.getDeviceNo()); basCrnp.setStatus(1); basCrnp.setInEnable("N"); basCrnp.setOutEnable("N"); basCrnp.setCreateTime(new Date()); basCrnpService.insert(basCrnp); } } } @Override public void close() { zyCrnConnectDriver.close(); } @Override public CrnProtocol getStatus() { return this.crnProtocol; } @Override public CrnCommand getPickAndPutCommand(String sourceLocNo, String targetLocNo, Integer taskNo, Integer crnNo) { CrnCommand crnCommand = new CrnCommand(); crnCommand.setCrnNo(crnNo); // 堆垛机编号 crnCommand.setTaskNo(taskNo.shortValue()); // 工作号 crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE.id.shortValue()); // 任务模式: 库位移转 crnCommand.setSourcePosX((short) Utils.getRow(sourceLocNo)); // 源库位排 crnCommand.setSourcePosY((short) Utils.getBay(sourceLocNo)); // 源库位列 crnCommand.setSourcePosZ((short) Utils.getLev(sourceLocNo)); // 源库位层 crnCommand.setDestinationPosX((short) Utils.getRow(targetLocNo)); // 目标库位排 crnCommand.setDestinationPosY((short) Utils.getBay(targetLocNo)); // 目标库位列 crnCommand.setDestinationPosZ((short) Utils.getLev(targetLocNo)); // 目标库位层 crnCommand.setCommand((short) 1); // 任务确认 return crnCommand; } @Override public CrnCommand getMoveCommand(String targetLocNo, Integer taskNo, Integer crnNo) { CrnCommand crnCommand = new CrnCommand(); crnCommand.setCrnNo(crnNo); // 堆垛机编号 crnCommand.setTaskNo(taskNo.shortValue()); // 工作号 crnCommand.setAckFinish((short) 0); // 任务完成确认位 crnCommand.setTaskMode(CrnTaskModeType.CRN_MOVE.id.shortValue()); // 任务模式: 堆垛机移动 crnCommand.setDestinationPosX((short) Utils.getRow(targetLocNo)); // 目标库位排 crnCommand.setDestinationPosY((short) Utils.getBay(targetLocNo)); // 目标库位列 crnCommand.setDestinationPosZ((short) Utils.getLev(targetLocNo)); // 目标库位层 crnCommand.setCommand((short) 1); // 任务确认 return crnCommand; } @Override public CrnCommand getResetCommand(Integer crnNo) { CrnCommand crnCommand = new CrnCommand(); crnCommand.setCrnNo(crnNo); // 堆垛机编号 crnCommand.setTaskNo((short) 0); // 工作号 crnCommand.setAckFinish((short) 1); // 任务完成确认位 crnCommand.setTaskMode(CrnTaskModeType.NONE.id.shortValue()); // 任务模式 crnCommand.setSourcePosX((short)0); // 源库位排 crnCommand.setSourcePosY((short)0); // 源库位列 crnCommand.setSourcePosZ((short)0); // 源库位层 crnCommand.setDestinationPosX((short)0); // 目标库位排 crnCommand.setDestinationPosY((short)0); // 目标库位列 crnCommand.setDestinationPosZ((short)0); // 目标库位层 crnCommand.setCommand((short) 1); // 任务确认 return crnCommand; } @Override public synchronized CommandResponse sendCommand(CrnCommand command) { this.crnProtocol.setLastCommandTime(System.currentTimeMillis()); return zyCrnConnectDriver.sendCommand(command); } }