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.core.common.Cools; import com.core.common.DateUtils; import com.core.common.SpringUtils; import com.zy.asrs.entity.BasDevp; import com.zy.asrs.service.BasDevpService; import com.zy.core.News; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.OutputQueue; import com.zy.core.enums.IoModeType; import com.zy.core.enums.SlaveType; import com.zy.core.model.DevpSlave; import com.zy.core.model.Task; import com.zy.core.model.protocol.StaProtocol; import com.zy.core.thread.DevpThread; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 输送线线程 * Created by vincent on 2020/8/4 */ @Data @Slf4j public class FyDevpThread implements Runnable, DevpThread { private DevpSlave slave; private SiemensS7Net siemensS7Net; private Map station = new ConcurrentHashMap<>(); public IoModeType ioModeOf2_5 = IoModeType.PAKOUT_MODE; private short heartBeatVal = 1; private int barcodeSize = 10; //写 public static final ArrayList staNos1 = new ArrayList() {{ add(1012); add(1014); add(1015); add(1022); add(1023); add(1025); add(1026); add(1031); add(1032); }}; //读 public static final ArrayList staNos2 = new ArrayList() {{ add(1011); add(1012); add(1013); add(1014); add(1015); add(1021); add(1022); add(1023); add(1024); add(1025); add(1026); add(1031); add(1032); }}; public FyDevpThread(DevpSlave slave) { this.slave = slave; } @Override @SuppressWarnings("InfiniteLoopStatement") public void run() { connect(); while (true) { try { int step = 1; Task task = MessageQueue.poll(SlaveType.Devp, slave.getId()); if (task != null) { step = task.getStep(); } switch (step) { // 读数据 case 1: read(); break; // 写数据 ID+目标站 case 2: write((StaProtocol) task.getData()); read(); break; default: break; } // 心跳 // heartbeat(); Thread.sleep(400); } catch (Exception e) { e.printStackTrace(); } } } @Override public boolean connect() { boolean result = false; siemensS7Net = new SiemensS7Net(SiemensPLCS.S1500, slave.getIp()); siemensS7Net.setRack(slave.getRack().byteValue()); siemensS7Net.setSlot(slave.getSlot().byteValue()); OperateResult connect = siemensS7Net.ConnectServer(); if (connect.IsSuccess) { result = true; OutputQueue.DEVP.offer(MessageFormat.format("【{0}】输送线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())); News.info("输送线plc连接成功 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); } else { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】输送线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())); News.error("输送线plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); } // siemensS7Net.ConnectClose(); return result; } /** * 读取状态 ====> 整块plc */ private void read() throws InterruptedException { // 更新入出库模式 updateIoMode(); int staNoSize = staNos2.size(); OperateResultExOne result = siemensS7Net.Read("DB82.14", (short) (staNoSize * 26)); if (result.IsSuccess) { for (int i = 0; i < staNoSize; i++) { Integer siteId = staNos2.get(i); StaProtocol staProtocol = station.get(staNos2.get(i)); if (null == staProtocol) { staProtocol = new StaProtocol(); staProtocol.setSiteId(siteId); if (siteId == 1015) { staProtocol.setLocNo("1200301"); } else if (siteId == 1026) { staProtocol.setLocNo("1200305"); } station.put(siteId, staProtocol); } Thread.sleep(300); boolean[] status = siemensS7Net.getByteTransform().TransBool(result.Content, i * 26, 2); staProtocol.setAutoing(status[0]); // 自动 staProtocol.setIdle(status[1]); //空闲 staProtocol.setLoading(status[2]); // 有物 staProtocol.setInEnable(status[3]); // 可入 staProtocol.setOutEnable(status[4]);// 可出 staProtocol.setBackErr(status[5]); staProtocol.setLeftErr(status[6]); staProtocol.setRightErr(status[7]); // staProtocol.setHighErr(status[8]); // staProtocol.setWeightErr(status[9]); // staProtocol.setLow(status[10]); // staProtocol.setHigh(status[11]); boolean[] status2 = siemensS7Net.getByteTransform().TransBool(result.Content, i * 26 + 1, 2); staProtocol.setHighErr(status2[0]); staProtocol.setWeightErr(status2[1]); staProtocol.setLow(status2[2]); staProtocol.setHigh(status2[3]); // staProtocol.setInEnable(status[13]); // 可入 // staProtocol.setOutEnable(status[14]);// 可出 staProtocol.setWorkNo(siemensS7Net.getByteTransform().TransInt16(result.Content, i * 26 + 2)); // 工作号 staProtocol.setStaNo(siemensS7Net.getByteTransform().TransInt16(result.Content, i * 26 + 4)); // 目标站 staProtocol.setFinishWorkNo(siemensS7Net.getByteTransform().TransInt16(result.Content, i * 26 + 6)); //已完成工作号 staProtocol.setBarcode(siemensS7Net.getByteTransform().TransString(result.Content, i * 26 + 10, 12, "UTF-8").trim()); //条码 staProtocol.setWeight(siemensS7Net.getByteTransform().TransInt32(result.Content, i * 26 + 22)); //重量 if (!staProtocol.isPakMk() && !staProtocol.isLoading()) { staProtocol.setPakMk(true); } } } if (!Cools.isEmpty(result) && result.IsSuccess) { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功", DateUtils.convert(new Date()), slave.getId())); // 根据实时信息更新数据库 try { BasDevpService basConveyorStaService = SpringUtils.getBean(BasDevpService.class); List stations = new ArrayList<>(); for (Integer sta : staNos2) { StaProtocol staProtocol = station.get(sta); BasDevp sqlModel = staProtocol.toSqlModel(); stations.add(sqlModel); //暂时写入数据库 BasDevp basDevp = basConveyorStaService.selectById(sta); if (basDevp == null) { basConveyorStaService.insert(sqlModel); } } if (!stations.isEmpty()) { if (null != basConveyorStaService && !basConveyorStaService.updateBatchById(stations)) { throw new Exception("更新数据库数据失败"); } } } catch (Exception e) { e.printStackTrace(); OutputQueue.DEVP.offer(MessageFormat.format("【{0}】更新数据库数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot())); News.error("更新数据库数据失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()); } } else { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】读取输送线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("读取输送线plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", device.getId(), device.getIp(), device.getPort(), device.getRack(), device.getSlot()); } } /** * 写入 ID+目标站 =====> 单站点写入 */ private void write(StaProtocol staProtocol) throws InterruptedException { if (null == staProtocol) { return; } int index = staNos1.indexOf(staProtocol.getSiteId()); index += 1; short[] array = new short[2]; array[0] = staProtocol.getStaNo(); array[1] = staProtocol.getWorkNo(); String staNoAddress = "DB83." + (index * 8 + 4); String workNoAddress = "DB83." + (index * 8 + 6); OperateResult write1 = siemensS7Net.Write(staNoAddress, array); if (!write1.IsSuccess) { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(array))); log.error("写入输送线站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(array)); return; } OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据成功。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(array))); log.info("写入输送线站点数据成功。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(array)); } /** * 心跳 */ private void heartbeat() { if (heartBeatVal == 1) { heartBeatVal = 2; } else { heartBeatVal = 1; } OperateResult write = siemensS7Net.Write("DB100.50", heartBeatVal); if (!write.IsSuccess) { News.error("输送线plc编号={} 心跳失败", slave.getId()); } } /** * 设置入库标记 */ @Override public void setPakMk(Integer siteId, boolean pakMk) { StaProtocol staProtocol = station.get(siteId); if (null != staProtocol) { staProtocol.setPakMk(pakMk); } } public synchronized void setOutInModel(Short staNo, Short outInModel) { String dbAddress = "DB51.4"; if (staNo == 105) { dbAddress = "DB51.4"; } else if (staNo == 205) { dbAddress = "DB51.10"; } else if (staNo == 346) { dbAddress = "DB51.12"; } else { News.error("模式切换失败,地址错误={},model={}", staNo, outInModel); return; } OperateResult write = siemensS7Net.Write(dbAddress, outInModel); if (!write.IsSuccess) { News.error("模式切换失败={},model={}", staNo, outInModel); } } @Override public void close() { siemensS7Net.ConnectClose(); } // 更新入出库模式 private void updateIoMode() { if (this.ioModeOf2_5 != null && (this.ioModeOf2_5.id == 0 || this.ioModeOf2_5.id == 1)) { short[] array = new short[1]; array[0] = this.ioModeOf2_5.id; if (!siemensS7Net.Write("DB83.80", this.ioModeOf2_5.id == 1).IsSuccess) { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线2.5F入出库模式失败", this.ioModeOf2_5)); log.error("【{0}】写入输送线2.5F入出库模式失败。输送线plc编号={}", this.ioModeOf2_5); } else { if (station.get(1031) != null) { station.get(1031).setOutInModel(this.ioModeOf2_5.id); station.get(1032).setOutInModel(this.ioModeOf2_5.id); } } } } }