package com.zy.core.network.real; 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.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.DateUtils; import com.core.common.SpringUtils; import com.zy.asrs.entity.BasDevp; import com.zy.asrs.entity.DeviceConfig; import com.zy.asrs.service.BasDevpService; import com.zy.common.utils.RedisUtil; import com.zy.core.News; import com.zy.core.cache.OutputQueue; import com.zy.core.enums.StationCommandType; import com.zy.core.model.CommandResponse; import com.zy.core.model.StationObjModel; import com.zy.core.model.command.StationCommand; import com.zy.core.network.api.ZyStationConnectApi; import com.zy.core.network.entity.ZyStationStatusEntity; import lombok.extern.slf4j.Slf4j; import java.text.MessageFormat; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; /** * 输送站真实连接(PLC) */ @Slf4j public class ZyStationV3RealConnect implements ZyStationConnectApi { private List statusList; private List barcodeOriginList; private SiemensS7Net siemensNet; private DeviceConfig deviceConfig; private RedisUtil redisUtil; private final static int taskAddressLength = 48; private final static int taskAddressLimit = 50; public ZyStationV3RealConnect(DeviceConfig deviceConfig, RedisUtil redisUtil) { this.deviceConfig = deviceConfig; this.redisUtil = redisUtil; } @Override public boolean connect() { boolean connected = false; siemensNet = new SiemensS7Net(SiemensPLCS.S1500, deviceConfig.getIp()); OperateResult connect = siemensNet.ConnectServer(); if (connect.IsSuccess) { connected = true; OutputQueue.DEVP.offer(MessageFormat.format("【{0}】输送站plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), deviceConfig.getDeviceNo(), deviceConfig.getIp(), deviceConfig.getPort())); News.info("输送站plc连接成功 ===>> [id:{}] [ip:{}] [port:{}]", deviceConfig.getDeviceNo(), deviceConfig.getIp(), deviceConfig.getPort()); } else { OutputQueue.DEVP.offer(MessageFormat.format("【{0}】输送站plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), deviceConfig.getDeviceNo(), deviceConfig.getIp(), deviceConfig.getPort())); News.error("输送站plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}]", deviceConfig.getDeviceNo(), deviceConfig.getIp(), deviceConfig.getPort()); } // siemensNet.ConnectClose(); return connected; } @Override public boolean disconnect() { siemensNet.ConnectClose(); return true; } @Override public List getStatus(Integer deviceNo) { if (statusList == null) { BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class); if (basDevpService == null) { return Collections.emptyList(); } BasDevp basDevp = basDevpService .selectOne(new EntityWrapper().eq("devp_no", deviceConfig.getDeviceNo())); if (basDevp == null) { return Collections.emptyList(); } statusList = JSONObject.parseArray(basDevp.getStationList(), ZyStationStatusEntity.class); if (statusList != null) { statusList.sort(Comparator.comparing(ZyStationStatusEntity::getStationId)); } barcodeOriginList = basDevp.getBarcodeStationList$(); } if (siemensNet == null) { return statusList; } OperateResultExOne result = siemensNet.Read("DB100.0", (short) (statusList.size() * 8)); if (result.IsSuccess) { for (int i = 0; i < statusList.size(); i++) { ZyStationStatusEntity statusEntity = statusList.get(i); // 站点编号 statusEntity.setTaskNo(siemensNet.getByteTransform().TransInt32(result.Content, i * 8)); // 工作号 statusEntity.setTargetStaNo((int) siemensNet.getByteTransform().TransInt16(result.Content, i * 8 + 4)); // 目标站 boolean[] status = siemensNet.getByteTransform().TransBool(result.Content, i * 8 + 6, 1); statusEntity.setAutoing(status[0]); // 自动 statusEntity.setLoading(status[1]); // 有物 statusEntity.setInEnable(status[2]); // 可入 statusEntity.setOutEnable(status[3]);// 可出 statusEntity.setEmptyMk(status[4]); // 空托盘 statusEntity.setFullPlt(status[5]); // 满托盘 boolean[] status2 = siemensNet.getByteTransform().TransBool(result.Content, i * 8 + 7, 1); statusEntity.setRunBlock(status2[1]);//重新规划路线 statusEntity.setEnableIn(status2[3]);//启动入库 Integer palletHeight = null; if (status[7]) { palletHeight = 1;//低 } if (status2[0]) { palletHeight = 2;//中 } if (status[6]) { palletHeight = 3;//高 } statusEntity.setPalletHeight(palletHeight);//高低信号 statusEntity.setError(0);//默认无报警 } } // 条码扫描器 OperateResultExOne result2 = siemensNet.Read("DB101.0", (short) (barcodeOriginList.size() * 16)); if (result2.IsSuccess) { for (int i = 0; i < barcodeOriginList.size(); i++) { ZyStationStatusEntity barcodeEntity = findStatusEntityByBarcodeIdx(i + 1); if (barcodeEntity == null) { continue; } String barcode = siemensNet.getByteTransform().TransString(result2.Content, i * 16 + 2, 14, "UTF-8"); barcode = barcode.trim(); barcodeEntity.setBarcode(barcode); } } // 称重 OperateResultExOne result3 = siemensNet.Read("DB102.0", (short) (barcodeOriginList.size() * 4)); if (result3.IsSuccess) { for (int i = 0; i < barcodeOriginList.size(); i++) { ZyStationStatusEntity barcodeEntity = findStatusEntityByBarcodeIdx(i + 1); if (barcodeEntity == null) { continue; } double weight = (double) siemensNet.getByteTransform().TransSingle(result3.Content, i * 4); barcodeEntity.setWeight(weight); } } // 报警信息 OperateResultExOne result4 = siemensNet.Read("DB103.0", (short) (barcodeOriginList.size() * 2)); if (result4.IsSuccess) { for (int i = 0; i < barcodeOriginList.size(); i++) { ZyStationStatusEntity barcodeEntity = findStatusEntityByBarcodeIdx(i + 1); if (barcodeEntity == null) { continue; } StringBuilder sb = new StringBuilder(); boolean[] status1 = siemensNet.getByteTransform().TransBool(result4.Content, i * 2, 1); boolean[] status2 = siemensNet.getByteTransform().TransBool(result4.Content, i * 2 + 1, 1); if(status1[0]){ sb.append("左超宽报警;"); } if(status1[1]) { sb.append("右超宽报警;"); } if(status1[2]) { sb.append("前超长报警;"); } if(status1[3]) { sb.append("后超长报警;"); } if(status1[4]) { sb.append("超高报警;"); } if(status1[5]) { sb.append("有货报警,空托入库时检测托盘上有无货物;"); } if(status1[6]) { sb.append("重量异常报警;"); } if(status1[7]) { sb.append("扫码异常;"); } if(sb.length() > 0) { barcodeEntity.setError(1); }else { barcodeEntity.setError(0); } barcodeEntity.setErrorMsg(sb.toString()); } } return statusList; } @Override public CommandResponse sendCommand(Integer deviceNo, StationCommand command) { CommandResponse commandResponse = new CommandResponse(false); if (null == command) { commandResponse.setMessage("命令为空"); return commandResponse; } int maxTryCount = 999; int tryCount = 0; if (command.getCommandType().equals(StationCommandType.MOVE)) { int enableCommandIdx = -1; while (true) { enableCommandIdx = getEnableCommandIdx(command.getTaskNo()); if(enableCommandIdx == -1) { try { Thread.sleep(300); }catch (Exception e) {} }else { break; } tryCount++; if (tryCount > maxTryCount) { commandResponse.setMessage("命令下发超时,无法找到可用下发区域"); return commandResponse; } } List pathList = command.getNavigatePath(); short[] data = new short[21]; data[0] = command.getTargetStaNo().shortValue(); int dataIdx = 1; for (Integer path : pathList) { data[dataIdx++] = path.shortValue(); } OperateResult writeTask = siemensNet.Write("DB23." + (enableCommandIdx * taskAddressLength), command.getTaskNo()); try { Thread.sleep(50); }catch (Exception e) {} OperateResult writeData = siemensNet.Write("DB23." + (enableCommandIdx * taskAddressLength + 4), data); try { Thread.sleep(200); }catch (Exception e) {} OperateResult writeConfirm = siemensNet.Write("DB23." + (enableCommandIdx * taskAddressLength + 46), (short) 1); if(writeTask.IsSuccess && writeData.IsSuccess && writeConfirm.IsSuccess) { log.error("写入输送线命令成功。任务号={},站点数据={}", command.getTaskNo(), JSON.toJSON(command)); commandResponse.setResult(true); }else { log.error("写入输送线命令失败。站点编号={},站点数据={}", command.getTaskNo(), JSON.toJSON(command)); commandResponse.setResult(false); } } else if (command.getCommandType().equals(StationCommandType.WRITE_INFO)) { int enableCommandIdx = -1; while (true) { enableCommandIdx = getEnableCommandIdx(command.getTaskNo()); if(enableCommandIdx == -1) { try { Thread.sleep(300); }catch (Exception e) {} }else { break; } tryCount++; if (tryCount > maxTryCount) { commandResponse.setMessage("命令下发超时,无法找到可用下发区域"); return commandResponse; } } short[] data = new short[21]; data[0] = command.getTargetStaNo().shortValue(); data[1] = command.getTargetStaNo().shortValue(); OperateResult writeTask = siemensNet.Write("DB23." + (enableCommandIdx * taskAddressLength), command.getTaskNo()); try { Thread.sleep(50); }catch (Exception e) {} OperateResult writeData = siemensNet.Write("DB23." + (enableCommandIdx * taskAddressLength + 4), data); try { Thread.sleep(200); }catch (Exception e) {} OperateResult writeConfirm = siemensNet.Write("DB23." + (enableCommandIdx * taskAddressLength + 46), (short) 1); if(writeTask.IsSuccess && writeData.IsSuccess && writeConfirm.IsSuccess) { log.error("写入输送线命令成功。任务号={},站点数据={}", command.getTaskNo(), JSON.toJSON(command)); commandResponse.setResult(true); }else { log.error("写入输送线命令失败。站点编号={},站点数据={}", command.getTaskNo(), JSON.toJSON(command)); commandResponse.setResult(false); } } return commandResponse; } @Override public CommandResponse sendOriginCommand(String address, short[] data) { CommandResponse commandResponse = new CommandResponse(false); if (null == data || data.length == 0) { commandResponse.setMessage("数据为空"); return commandResponse; } OperateResult write = siemensNet.Write(address, data); if (write.IsSuccess) { log.info("写入原始命令成功。地址={},数据={}", address, JSON.toJSON(data)); commandResponse.setResult(true); } else { log.error("写入原始命令失败。地址={},数据={}", address, JSON.toJSON(data)); commandResponse.setResult(false); } return commandResponse; } @Override public byte[] readOriginCommand(String address, int length) { OperateResultExOne result = siemensNet.Read(address, (short) length); if (result.IsSuccess) { return result.Content; } return new byte[0]; } private ZyStationStatusEntity findStatusEntityByBarcodeIdx(Integer barcodeIdx) { Integer stationId = null; for (StationObjModel stationObjModel : barcodeOriginList) { if (stationObjModel.getBarcodeIdx().equals(barcodeIdx)) { stationId = stationObjModel.getStationId(); break; } } for (ZyStationStatusEntity zyStationStatusEntity : statusList) { if(zyStationStatusEntity.getStationId().equals(stationId)) { return zyStationStatusEntity; } } return null; } private int getEnableCommandIdx(int taskNo) { int useIdx = -1; for (int i = 0; i < taskAddressLimit; i++) { OperateResultExOne resultTask = siemensNet.Read("DB23." + (i * taskAddressLength + 0), (short) 4); OperateResultExOne resultStatus = siemensNet.Read("DB23." + (i * taskAddressLength + 46), (short) 2); if(!resultTask.IsSuccess || !resultStatus.IsSuccess) { continue; } int commandAreaTaskNo = siemensNet.getByteTransform().TransInt32(resultTask.Content, 0); if(commandAreaTaskNo == taskNo) { return -1; } int taskStatus = siemensNet.getByteTransform().TransInt16(resultStatus.Content, 0); if (taskStatus == 1) { continue; } useIdx = i; break; } return useIdx; } }