|  |  | 
 |  |  | 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.Cools; | 
 |  |  | import com.zy.asrs.framework.common.DateUtils; | 
 |  |  | import com.zy.asrs.framework.common.SpringUtils; | 
 |  |  | import com.zy.asrs.wcs.core.entity.BasConveyor; | 
 |  |  | import com.zy.asrs.wcs.core.entity.BasConveyorSta; | 
 |  |  | import com.zy.asrs.wcs.core.service.BasConveyorService; | 
 |  |  | import com.zy.asrs.wcs.core.service.BasConveyorStaService; | 
 |  |  | import com.zy.asrs.wcs.core.utils.RedisUtil; | 
 |  |  | 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.model.dto.WorkModeTypeDto; | 
 |  |  | import com.zy.asrs.wcs.rcs.model.enums.WorkModeType; | 
 |  |  | import com.zy.asrs.wcs.rcs.model.protocol.StaProtocol; | 
 |  |  | import com.zy.asrs.wcs.rcs.thread.DevpThread; | 
 |  |  | 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; | 
 |  |  |  | 
 |  |  | public class SiemensDevpThread implements DevpThread { | 
 |  |  | @Slf4j | 
 |  |  | public class SiemensDevpThread implements DevpThread, Runnable { | 
 |  |  |  | 
 |  |  |     private Device device; | 
 |  |  |     private RedisUtil redisUtil; | 
 |  |  |     private SiemensS7Net siemensS7Net; | 
 |  |  |  | 
 |  |  |     private Map<Integer, StaProtocol> station = new ConcurrentHashMap<>(); | 
 |  |  |  | 
 |  |  |     public static ArrayList<BasConveyorSta> stationList = new ArrayList<>(); | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 条码数量 | 
 |  |  |      */ | 
 |  |  |     private int barcodeSize = 2; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 入出库模式 | 
 |  |  |      * 0:未知 | 
 |  |  |      * 1:入库启动中 | 
 |  |  |      * 2.入库模式 | 
 |  |  |      * 3.出库启动中 (不能生成入库工作档) | 
 |  |  |      * 4.出库模式 | 
 |  |  |      */ | 
 |  |  |     private Map<Integer, WorkModeTypeDto> workModeTypes = new ConcurrentHashMap<>(); | 
 |  |  |  | 
 |  |  |     public SiemensDevpThread(Device device, RedisUtil redisUtil) { | 
 |  |  |         this.device = device; | 
 |  |  |         this.redisUtil = redisUtil; | 
 |  |  |  | 
 |  |  |         workModeTypes.put(101, new WorkModeTypeDto(101, WorkModeType.NONE, "DB1001.120")); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     private ArrayList<BasConveyorSta> getStaNo() { | 
 |  |  |         try { | 
 |  |  |             if (stationList.isEmpty()) { | 
 |  |  |                 BasConveyorService basConveyorService = SpringUtils.getBean(BasConveyorService.class); | 
 |  |  |                 BasConveyorStaService basConveyorStaService = SpringUtils.getBean(BasConveyorStaService.class); | 
 |  |  |                 BasConveyor basConveyor = basConveyorService.getOne(new LambdaQueryWrapper<BasConveyor>() | 
 |  |  |                         .eq(BasConveyor::getDeviceId, device.getId()) | 
 |  |  |                         .eq(BasConveyor::getHostId, device.getHostId())); | 
 |  |  |                 if(basConveyor != null) { | 
 |  |  |                     List<BasConveyorSta> stations = basConveyorStaService.list(new LambdaQueryWrapper<BasConveyorSta>() | 
 |  |  |                             .eq(BasConveyorSta::getConveyorId, basConveyor.getId()) | 
 |  |  |                             .eq(BasConveyorSta::getHostId, device.getHostId())); | 
 |  |  |                     stationList.addAll(stations); | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |             return stationList; | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             return stationList; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public boolean writeWorkNo(short workNo) { | 
 |  |  |     @SuppressWarnings("InfiniteLoopStatement") | 
 |  |  |     public void run() { | 
 |  |  |         News.info("{}号输送线线程启动", device.getDeviceNo()); | 
 |  |  |         this.connect(); | 
 |  |  |         while (true) { | 
 |  |  |             try { | 
 |  |  |                 read(); | 
 |  |  |                 Thread.sleep(500); | 
 |  |  |             } catch (Exception e) { | 
 |  |  |                 e.printStackTrace(); | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     private void read() throws InterruptedException { | 
 |  |  |         ArrayList<BasConveyorSta> staNos = getStaNo(); | 
 |  |  |         int staNoSize = staNos.size(); | 
 |  |  |         OperateResultExOne<byte[]> result = siemensS7Net.Read("DB101.0", (short) (staNoSize*8)); | 
 |  |  |         if (result.IsSuccess) { | 
 |  |  |             for (int i = 0; i < staNoSize; i++) { | 
 |  |  |                 BasConveyorSta siteStation = staNos.get(i); | 
 |  |  |                 int siteId = siteStation.getSiteNo();// 站点编号 | 
 |  |  |                 StaProtocol staProtocol = station.get(siteId); | 
 |  |  |                 if (null == staProtocol) { | 
 |  |  |                     staProtocol = new StaProtocol(); | 
 |  |  |                     staProtocol.setSiteId(siteId); | 
 |  |  |                     station.put(siteId, staProtocol); | 
 |  |  |                 } | 
 |  |  |                 staProtocol.setStaNo( siemensS7Net.getByteTransform().TransInt16(result.Content, i*8 + 4 ));   // 目标站 | 
 |  |  |                 Thread.sleep(300); | 
 |  |  |                 staProtocol.setWorkNo((short) siemensS7Net.getByteTransform().TransInt32(result.Content, i * 8));     // 工作号 | 
 |  |  |  | 
 |  |  |                 boolean[] status = siemensS7Net.getByteTransform().TransBool(result.Content, i*8+6, 2); | 
 |  |  |                 staProtocol.setAutoing(status[0]);  // 自动 | 
 |  |  |                 staProtocol.setLoading(status[1]);  // 有物 | 
 |  |  |                 staProtocol.setInEnable(status[2]); // 可入 | 
 |  |  |                 staProtocol.setOutEnable(status[3]);// 可出 | 
 |  |  |                 staProtocol.setEmptyMk(status[4]);  // 空板信号 | 
 |  |  |                 staProtocol.setFullPlt(status[5]);  // 满托盘 | 
 |  |  |                 staProtocol.setHigh(status[6]);     // 高库位 | 
 |  |  |                 staProtocol.setLow(status[7]);      // 低库位 | 
 |  |  |  | 
 |  |  |                 if (!staProtocol.isPakMk() && !staProtocol.isLoading()) { | 
 |  |  |                     staProtocol.setPakMk(true); | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         Thread.sleep(200); | 
 |  |  |         ArrayList<BasConveyorSta> errorStaNo = getStaNo(); | 
 |  |  |         OperateResultExOne<byte[]> result3 = siemensS7Net.Read("DB101.800.0", (short) (errorStaNo.size() * 4)); | 
 |  |  |         if (result3.IsSuccess) { | 
 |  |  |             for (int i = 0; i < errorStaNo.size(); i++) { | 
 |  |  |                 BasConveyorSta siteStation = errorStaNo.get(i); | 
 |  |  |                 Integer siteId = siteStation.getSiteNo(); // 站点编号 | 
 |  |  |                 StaProtocol staProtocol = station.get(siteId); | 
 |  |  |                 boolean[] status = siemensS7Net.getByteTransform().TransBool(result3.Content, (i * 4 + 2), 2); | 
 |  |  |                 staProtocol.setFrontErr(status[0]);//前超限 | 
 |  |  |                 staProtocol.setBackErr(status[1]);//后超限 | 
 |  |  |                 staProtocol.setHighErr(status[2]);//超高 | 
 |  |  |                 staProtocol.setLeftErr(status[3]);//左超限 | 
 |  |  |                 staProtocol.setRightErr(status[4]);//右超限 | 
 |  |  |                 staProtocol.setWeightErr(status[5]);//超重 | 
 |  |  |                 staProtocol.setBarcodeErr(status[6]);//扫码失败 | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         if (!Cools.isEmpty(result) && result.IsSuccess) { | 
 |  |  |  | 
 |  |  |             OutputQueue.DEVP.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), device.getId())); | 
 |  |  |  | 
 |  |  |             // 根据实时信息更新数据库 | 
 |  |  |             try { | 
 |  |  |                 List<BasConveyorSta> stations = new ArrayList<>(); | 
 |  |  |                 for (BasConveyorSta sta : getStaNo()) { | 
 |  |  |                     StaProtocol staProtocol = station.get(sta.getSiteNo()); | 
 |  |  |                     BasConveyorSta sqlModel = staProtocol.toSqlModel(sta); | 
 |  |  |                     stations.add(sqlModel); | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 if (!stations.isEmpty()) { | 
 |  |  |                     BasConveyorStaService basConveyorStaService = SpringUtils.getBean(BasConveyorStaService.class); | 
 |  |  |                     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()), device.getId(), device.getIp(), device.getPort(), device.getRack(), device.getSlot())); | 
 |  |  |                 News.error("更新数据库数据失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", device.getId(), device.getIp(), device.getPort(), device.getRack(), device.getSlot()); | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |         } else { | 
 |  |  |             OutputQueue.DEVP.offer(MessageFormat.format("【{0}】读取输送线plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), device.getId(), device.getIp(), device.getPort(), device.getRack(), device.getSlot())); | 
 |  |  | //            log.error("读取输送线plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", device.getId(), device.getIp(), device.getPort(), device.getRack(), device.getSlot()); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public boolean connect() { | 
 |  |  |         boolean result = false; | 
 |  |  |         siemensS7Net = new SiemensS7Net(SiemensPLCS.S1200, device.getIp()); | 
 |  |  |         siemensS7Net.setRack(device.getRack().byteValue()); | 
 |  |  |         siemensS7Net.setSlot(device.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()), device.getId(), device.getIp(), device.getPort(), device.getRack(), device.getSlot())); | 
 |  |  |             News.info("输送线plc连接成功 ===>> [id:{}] [ip:{}] [port:{}]", device.getId(), device.getIp(), device.getPort()); | 
 |  |  |         } else { | 
 |  |  |             OutputQueue.DEVP.offer(MessageFormat.format( "【{0}】输送线plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}]  [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), device.getId(), device.getIp(), device.getPort(), device.getRack(), device.getSlot())); | 
 |  |  |             News.error("输送线plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}]", device.getId(), device.getIp(), device.getPort()); | 
 |  |  |         } | 
 |  |  |         // siemensS7Net.ConnectClose(); | 
 |  |  |         return result; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public void close() { | 
 |  |  |  | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public boolean writeWorkNo(int siteId, short workNo) { | 
 |  |  |         int index = findStaNosIndex(siteId); | 
 |  |  |  | 
 |  |  |         OperateResult write = siemensS7Net.Write("DB100." + index*6, workNo);    // 工作号 | 
 |  |  |  | 
 |  |  |         if (!write.IsSuccess) { | 
 |  |  |             StaProtocol staProtocol = station.get(siteId); | 
 |  |  |             if (staProtocol.getWorkNo() == 0 && staProtocol.getStaNo() ==0) { | 
 |  |  |                 staProtocol.setPakMk(true); | 
 |  |  |             } | 
 |  |  |             OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", device.getId(), JSON.toJSON(staProtocol))); | 
 |  |  |             log.error("写入输送线站点数据失败。输送线plc编号={},站点数据={}", device.getId(), JSON.toJSON(staProtocol)); | 
 |  |  |         } else { | 
 |  |  |             OutputQueue.DEVP.offer(MessageFormat.format("【{0}】 输送线命令下发 [id:{1}] >>>>> {2}", DateUtils.convert(new Date()), device.getId(), JSON.toJSON(workNo))); | 
 |  |  |             log.info("输送线命令下发 [id:{}] >>>>> 命令下发: {}",  device.getId(), JSON.toJSON(workNo)); | 
 |  |  |             return true; | 
 |  |  |         } | 
 |  |  |         return false; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public boolean writeStaNo(short staNo) { | 
 |  |  |     public boolean writeStaNo(int siteId,short staNo) { | 
 |  |  |         int index = findStaNosIndex(siteId); | 
 |  |  |  | 
 |  |  |         OperateResult write = siemensS7Net.Write("DB100." + (index*6+4), staNo);    // 目标站 | 
 |  |  |  | 
 |  |  |         if (!write.IsSuccess) { | 
 |  |  |             StaProtocol staProtocol = station.get(siteId); | 
 |  |  |             if (staProtocol.getWorkNo() == 0 && staProtocol.getStaNo() ==0) { | 
 |  |  |                 staProtocol.setPakMk(true); | 
 |  |  |             } | 
 |  |  |             OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", device.getId(), JSON.toJSON(staProtocol))); | 
 |  |  |             log.error("写入输送线站点数据失败。输送线plc编号={},站点数据={}", device.getId(), JSON.toJSON(staProtocol)); | 
 |  |  |         } else { | 
 |  |  |             OutputQueue.DEVP.offer(MessageFormat.format("【{0}】 输送线命令下发 [id:{1}] >>>>> {2}", DateUtils.convert(new Date()), device.getId(), JSON.toJSON(staNo))); | 
 |  |  |             log.info("输送线命令下发 [id:{}] >>>>> 命令下发: {}",  device.getId(), JSON.toJSON(staNo)); | 
 |  |  |             return true; | 
 |  |  |         } | 
 |  |  |         return false; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public boolean writeWorkSta(int siteId, short workNo, short staNo) { | 
 |  |  |         int index = findStaNosIndex(siteId); | 
 |  |  |  | 
 |  |  |         OperateResult write1 = siemensS7Net.Write("DB100." + index*6, workNo);    // 工作号 | 
 |  |  |         OperateResult write2 = siemensS7Net.Write("DB100." + (index*6+4), staNo);    // 目标站 | 
 |  |  |  | 
 |  |  |         if (!(write1.IsSuccess && write2.IsSuccess)) { | 
 |  |  |             StaProtocol staProtocol = station.get(siteId); | 
 |  |  |             if (staProtocol.getWorkNo() == 0 && staProtocol.getStaNo() ==0) { | 
 |  |  |                 staProtocol.setPakMk(true); | 
 |  |  |             } | 
 |  |  |             OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", device.getId(), JSON.toJSON(staProtocol))); | 
 |  |  |             log.error("写入输送线站点数据失败。输送线plc编号={},站点数据={}", device.getId(), JSON.toJSON(staProtocol)); | 
 |  |  |         } else { | 
 |  |  |             OutputQueue.DEVP.offer(MessageFormat.format("【{0}】 输送线命令下发 [id:{1}] >>>>> {2}", DateUtils.convert(new Date()), device.getId(), JSON.toJSON(staNo))); | 
 |  |  |             log.info("输送线命令下发 [id:{}] >>>>> 命令下发: {}",  device.getId(), JSON.toJSON(staNo)); | 
 |  |  |             return true; | 
 |  |  |         } | 
 |  |  |         return false; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public Map<Integer, StaProtocol> getStation() { | 
 |  |  |         return this.station; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     private int findStaNosIndex(int siteId) { | 
 |  |  |         ArrayList<BasConveyorSta> staNos = getStaNo(); | 
 |  |  |  | 
 |  |  |         int index = -1; | 
 |  |  |         for (int i = 0; i < staNos.size(); i++) { | 
 |  |  |             BasConveyorSta sta = staNos.get(i); | 
 |  |  |             if (sta.getSiteNo() == siteId) { | 
 |  |  |                 index = i; | 
 |  |  |                 break; | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |         return index; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 设置入库标记 | 
 |  |  |      */ | 
 |  |  |     @Override | 
 |  |  |     public void setPakMk(Integer siteId, boolean pakMk) { | 
 |  |  |         StaProtocol staProtocol = station.get(siteId); | 
 |  |  |         if (null != staProtocol) { | 
 |  |  |             staProtocol.setPakMk(pakMk); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     private void updateWorkMode() { | 
 |  |  |         for (Map.Entry<Integer, WorkModeTypeDto> entry : workModeTypes.entrySet()) { | 
 |  |  |             WorkModeTypeDto workModeTypeDto = entry.getValue(); | 
 |  |  |             WorkModeType workModeType = workModeTypeDto.getWorkModeType(); | 
 |  |  |             if (workModeType != WorkModeType.NONE) { | 
 |  |  |                 if (!siemensS7Net.Write(workModeTypeDto.getAddress(), workModeType.id).IsSuccess) { | 
 |  |  |                     OutputQueue.DEVP.offer(MessageFormat.format("写入输送线{1}入出库模式失败。输送线编号={0}", device.getId(), workModeTypeDto.getSiteId())); | 
 |  |  |                     log.error("写入输送线{1}入出库模式失败。输送线编号={0}", device.getId(), workModeTypeDto.getSiteId()); | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public boolean switchWorkMode(int siteId, int workMode) { | 
 |  |  |         WorkModeTypeDto workModeTypeDto = workModeTypes.get(siteId); | 
 |  |  |         if(workModeTypeDto == null) { | 
 |  |  |             return false; | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         workModeTypeDto.setWorkModeType(WorkModeType.get((short) workMode)); | 
 |  |  |         workModeTypes.put(siteId, workModeTypeDto); | 
 |  |  |         return false; | 
 |  |  |     } | 
 |  |  | } |