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.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 ZyStationV4RealConnect implements ZyStationConnectApi {
|
|
private List<ZyStationStatusEntity> statusList;
|
private List<StationObjModel> barcodeOriginList;
|
private SiemensS7Net siemensNet;
|
private DeviceConfig deviceConfig;
|
private RedisUtil redisUtil;
|
|
public ZyStationV4RealConnect(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());
|
}
|
// 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));
|
}
|
barcodeOriginList = basDevp.getBarcodeStationList$();
|
}
|
|
if (siemensNet == null) {
|
return statusList;
|
}
|
|
OperateResultExOne<byte[]> result = siemensNet.Read("DB100.0", (short) (statusList.size() * 10));
|
if (result.IsSuccess) {
|
for (int i = 0; i < statusList.size(); i++) {
|
ZyStationStatusEntity statusEntity = statusList.get(i); // 站点编号
|
statusEntity.setTaskNo(siemensNet.getByteTransform().TransInt32(result.Content, i * 10)); // 工作号
|
statusEntity.setTargetStaNo((int) siemensNet.getByteTransform().TransInt16(result.Content, i * 10 + 4)); // 目标站
|
|
boolean[] status = siemensNet.getByteTransform().TransBool(result.Content, i * 10 + 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 * 10 + 7, 1);
|
statusEntity.setEnableIn(status2[1]);//启动入库
|
|
Integer palletHeight = null;
|
if (status[7]) {
|
palletHeight = 1;//低
|
}
|
if (status2[0]) {
|
palletHeight = 2;//中
|
}
|
if (status[6]) {
|
palletHeight = 3;//高
|
}
|
statusEntity.setPalletHeight(palletHeight);//高低信号
|
|
statusEntity.setError(0);//默认无报警
|
|
statusEntity.setTaskWriteIdx((int) siemensNet.getByteTransform().TransInt16(result.Content, i * 10 + 8));//任务可写区
|
}
|
}
|
|
// 条码扫描器
|
OperateResultExOne<byte[]> result2 = siemensNet.Read("DB101.16", (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<byte[]> result3 = siemensNet.Read("DB102.4", (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<byte[]> result4 = siemensNet.Read("DB103.2", (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 taskWriteIdx = getTaskWriteIdx(command.getStationId());
|
if (taskWriteIdx == -1) {
|
commandResponse.setMessage("命令下发超时,无法找到可用下发区域");
|
return commandResponse;
|
}
|
|
int stationIdx = findIndex(command.getStationId());
|
|
short[] data = new short[2];
|
data[0] = (short) 0;
|
data[1] = command.getTargetStaNo().shortValue();
|
|
OperateResult writeTaskNo = siemensNet.Write("DB13." + (stationIdx * 48 + (taskWriteIdx * 12)), command.getTaskNo());
|
if (!writeTaskNo.IsSuccess) {
|
log.error("写入输送线命令失败。站点编号={},站点数据={}", command.getTaskNo(), JSON.toJSON(command));
|
commandResponse.setResult(false);
|
commandResponse.setMessage("命令下发失败,写入工作号失败");
|
return commandResponse;
|
}
|
|
OperateResult writeData = siemensNet.Write("DB13." + (stationIdx * 48 + (taskWriteIdx * 12 + 4)), data);
|
if (!writeData.IsSuccess) {
|
log.error("写入输送线命令失败。站点编号={},站点数据={}", command.getTaskNo(), JSON.toJSON(command));
|
commandResponse.setResult(false);
|
commandResponse.setMessage("命令下发失败,写入数据区域失败");
|
return commandResponse;
|
}
|
|
log.info("写入输送线命令成功。任务号={},站点数据={}", command.getTaskNo(), JSON.toJSON(command));
|
commandResponse.setResult(true);
|
return commandResponse;
|
}
|
|
@Override
|
public synchronized 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 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 getTaskWriteIdx(int stationId) {
|
int useIdx = -1;
|
|
int stationIdx = findIndex(stationId);
|
if (stationIdx != -1) {
|
ZyStationStatusEntity statusEntity = statusList.get(stationIdx);
|
|
Integer taskWriteIdx = statusEntity.getTaskWriteIdx();
|
if (taskWriteIdx > 0) {
|
OperateResultExOne<byte[]> resultTask = siemensNet.Read("DB13." + (stationId * 48), (short) 48);
|
if (resultTask.IsSuccess) {
|
int taskNo = siemensNet.getByteTransform().TransInt32(resultTask.Content, taskWriteIdx * 12);
|
int startPoint = siemensNet.getByteTransform().TransInt16(resultTask.Content, taskWriteIdx * 12 + 4);
|
int targetPoint = siemensNet.getByteTransform().TransInt16(resultTask.Content, taskWriteIdx * 12 + 6);
|
if (taskNo == 0 && startPoint == 0 && targetPoint == 0) {
|
useIdx = taskWriteIdx;
|
}
|
}
|
}
|
}
|
|
return useIdx;
|
}
|
|
private int findIndex(Integer stationId) {
|
for (int i = 0; i < statusList.size(); i++) {
|
ZyStationStatusEntity statusEntity = statusList.get(i);
|
if (statusEntity.getStationId().equals(stationId)) {
|
return i;
|
}
|
}
|
return -1;
|
}
|
|
}
|