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<ZyStationStatusEntity> statusList;
|
private List<ZyStationStatusEntity> 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.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<ZyStationStatusEntity> getStatus(Integer deviceNo) {
|
if (statusList == null) {
|
BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class);
|
if (basDevpService == null) {
|
return Collections.emptyList();
|
}
|
|
BasDevp basDevp = basDevpService
|
.selectOne(new EntityWrapper<BasDevp>().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));
|
}
|
}
|
|
if (siemensNet == null) {
|
return statusList;
|
}
|
|
OperateResultExOne<byte[]> 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<byte[]> 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;
|
}
|
|
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<Integer> 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);
|
}
|
}
|
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<byte[]> 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 taskNo) {
|
int useIdx = -1;
|
for (int i = 0; i < taskAddressLimit; i++) {
|
OperateResultExOne<byte[]> resultTask = siemensNet.Read("DB23." + (i * taskAddressLength + 0), (short) 2);
|
OperateResultExOne<byte[]> 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;
|
}
|
|
}
|