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.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 barcodeStatusList; 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.S1200, 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()); } 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)); } barcodeStatusList = JSONObject.parseArray(basDevp.getBarcodeStationList(), ZyStationStatusEntity.class); if (barcodeStatusList != null) { barcodeStatusList.sort(Comparator.comparing(ZyStationStatusEntity::getStationId)); } } 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]);//启动入库 } } // 条码扫描器 OperateResultExOne result2 = siemensNet.Read("DB101.0", (short) (statusList.size() * 10)); if (result2.IsSuccess) { for (int i = 0; i < barcodeStatusList.size(); i++) { ZyStationStatusEntity barcodeEntity = barcodeStatusList.get(i); ZyStationStatusEntity statusEntity = findStatusEntity(barcodeEntity.getStationId()); if (statusEntity == null) { continue; } String barcode = siemensNet.getByteTransform().TransString(result2.Content, i * 10 + 2, 8, "UTF-8"); barcode = barcode.trim(); barcodeEntity.setBarcode(barcode); } } return statusList; } @Override public CommandResponse sendCommand(Integer deviceNo, StationCommand command) { CommandResponse commandResponse = new CommandResponse(false); if (null == command) { commandResponse.setMessage("命令为空"); return commandResponse; } if (command.getCommandType().equals(StationCommandType.MOVE)) { int enableCommandIdx = -1; while (true) { enableCommandIdx = getEnableCommandIdx(); if(enableCommandIdx == -1) { try { Thread.sleep(300); }catch (Exception e) {} }else { break; } } List pathList = command.getNavigatePath(); short[] data = new short[22]; 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()); OperateResult writeData = siemensNet.Write("DB23." + enableCommandIdx * taskAddressLength + 4, data); if(writeTask.IsSuccess && writeData.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 findStatusEntity(Integer stationId) { for (ZyStationStatusEntity statusEntity : statusList) { if (statusEntity.getStationId().equals(stationId)) { return statusEntity; } } return null; } private int getEnableCommandIdx() { int useIdx = -1; for (int i = 0; i < taskAddressLimit; i++) { OperateResultExOne result = siemensNet.Read("DB23." + i * taskAddressLength, (short) taskAddressLength); int taskStatus = siemensNet.getByteTransform().TransInt16(result.Content, i * taskAddressLength + 46); if (taskStatus == 1) { continue; } useIdx = i; break; } return useIdx; } }