Merge remote-tracking branch 'origin/main'

This commit is contained in:
zgw
2025-11-18 13:14:15 +08:00
4 changed files with 258 additions and 57 deletions

View File

@@ -18,69 +18,40 @@ import lombok.NoArgsConstructor;
public class DeviceSrgv extends BaseEntity public class DeviceSrgv extends BaseEntity
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/*
* 实时数据
* */
private int taskNo;//任务号
private String srcSite;//原地址
private String tarSite;//目标地址
private String currSite;//当期地址
/** $column.columnComment */ private int taskType;//任务类型
private Long id;
/** 设备唯一编码 */ private int battery;//电量
@Excel(name = "设备唯一编码") private int workMode;//工作模式
private String deviceCode ; private int alarm;//报警
private int status;//车状态
private int finish;//接收完成标志 1接收完成
private int chargeFlag;//充电标志 todo 充电状态值确认
private int workPhase;//工作阶段
private int errorMsg;//异常信息
private int deviceRequest;//输送机对接请求
private int changeLayer;//换层标志
private int cargoFlag;//载货 0未知 1空载 2载货
private int manualCharge;//手动充电 0未知 1充电
/** 设备名称 */ private int undefined1;//
@Excel(name = "设备名称") private int undefined2;//
private String name ;
/** 类型 */ private String path;//路径
@Excel(name = "类型")
private String type;
/** 设备IP */ //其他属性
@Excel(name = "设备IP") private int currFloor;//当前层
private String ipAddress;
/** PLC读取地址 */ private String spaceArea;//当前库存 01小库 02大库
@Excel(name = "PLC读取地址")
private String plcDbReadAddress;
/** 0-F 1-T */ private int allowSend;//1允许下发
@Excel(name = "0-F 1-T")
private String isActive;
/** PLC写入地址 */
@Excel(name = "PLC写入地址")
private String plcDbWriteAddress;
/** 入库请求 */
@Excel(name = "入库请求")
private int rkqq;
/** 空闲 */
@Excel(name = "空闲")
private int kx;
/** 到位 */
@Excel(name = "到位")
private int dw;
/** 条码 */
@Excel(name = "条码")
private String trayCode;
/** 任务号 */
@Excel(name = "任务号")
private int taskNo;
@Excel(name = "异常")
private int exception;
@Excel(name = "托盘尺寸")
private int traySize;
@Excel(name="允许放货")
private int allowPut;
@Excel(name="输送线模式 1-入库 2-出库")
private int model;

View File

@@ -17,7 +17,7 @@ import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@Slf4j @Slf4j
public class PlcDdjRead extends Thread { public class PlcDdjRead implements Runnable {
public static ConcurrentHashMap<String, MsgDdj> deviceDdjMap; public static ConcurrentHashMap<String, MsgDdj> deviceDdjMap;
public volatile boolean isRun = true; public volatile boolean isRun = true;

View File

@@ -0,0 +1,33 @@
package com.ruoyi.schedule.plcRead.srgv;
public class FloorUtils {
/**
* 从cur值中提取楼层信息
* @param cur 原始楼层值
* @return 处理后的楼层值,如果小于等于0则返回0
*/
public static int extractFloor(Integer cur) {
// 处理null值
if (cur == null) {
return 0;
}
// 获取后两位(处理负数情况)
int floor = Math.abs(cur) % 100;
// 如果结果小于等于0,返回默认值0
return floor <= 0 ? 0 : floor;
}
/**
* 重载方法,处理int类型
*/
public static int extractFloor(int cur) {
// 获取后两位(处理负数情况)
int floor = Math.abs(cur) % 100;
// 如果结果小于等于0,返回默认值0
return floor <= 0 ? 0 : floor;
}
}

View File

@@ -0,0 +1,197 @@
package com.ruoyi.schedule.plcRead.srgv;
import HslCommunication.Core.Net.IReadWriteNet;
import HslCommunication.Core.Transfer.DataFormat;
import HslCommunication.Core.Transfer.IByteTransform;
import HslCommunication.Core.Types.OperateResult;
import HslCommunication.Core.Types.OperateResultExOne;
import HslCommunication.ModBus.ModbusTcpNet;
import com.ruoyi.common.domain.HslRead;
import com.ruoyi.common.domain.PlcConnectInfo;
import com.ruoyi.device.srgv.domain.DeviceSrgv;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
public class PlcSrgvRead implements Runnable{
public static ConcurrentHashMap<String, DeviceSrgv> deviceSrgvMap;
private ModbusTcpNet modbusTcpNet;
public static IReadWriteNet readWriteNet = null;
public volatile boolean isRun = true;
private final String ip;
private final int port;
private byte station;
private Integer layer;
private boolean success = false;
private IByteTransform byteTransform = null;
public PlcSrgvRead(ConcurrentHashMap<String, DeviceSrgv> deviceSrgvMap, PlcConnectInfo plcConnectInfo){
PlcSrgvRead.deviceSrgvMap = deviceSrgvMap;
this.ip = plcConnectInfo.getIp();
this.port = plcConnectInfo.getPort();
this.station=(byte)1;
}
public static int WriteToSSJ(String address, byte[] data) {
int a = 0;
if (readWriteNet != null) {
a = HslRead.WriteResultRender(readWriteNet.Write(address, data), address);
}
return a;
}
@Override
public void run() {
while (isRun) {
try {
if (IsConnect()) {
for(String srgvId:deviceSrgvMap.keySet()){
DeviceSrgv deviceSrgv = deviceSrgvMap.get(srgvId);
if(deviceSrgv!=null){
readSrgvPlc(deviceSrgv);
}
}
Thread.sleep(1000);
} else {
reConnect();
}
}catch (InterruptedException e) {
// 捕获中断异常,退出循环
Thread.currentThread().interrupt(); // 重新设置中断标志
return;
} catch (Exception e) {
log.info("********IP:" + this.ip + " port:" + this.port + "读取数据异常 " + e.getMessage());
}
}
}
private void readSrgvPlc(DeviceSrgv deviceSrgv){
OperateResultExOne<byte[]> read1 = modbusTcpNet.Read("2400",(short)15);//2400-2414
if (read1.IsSuccess) {
setValueByByte1(read1.Content,deviceSrgv);
}
//读取双字
OperateResultExOne<byte[]> read2 = modbusTcpNet.Read("4800",(short)8);// 4800-4807任务号、原点、目标点、当前
if(read2.IsSuccess){
setValueByByte2(read2.Content,deviceSrgv);
}
//读取双字,路径
OperateResultExOne<byte[]> read3 = modbusTcpNet.Read("5000",(short)800);// 5000-5799 路径 400个
setValueByByte3(read3.Content,deviceSrgv);
}
//单字
private void setValueByByte1(byte[] content , DeviceSrgv agvData) {
agvData.setTaskType(byteTransform.TransInt16(content,0));
agvData.setBattery(byteTransform.TransInt16(content,2));
agvData.setWorkMode(byteTransform.TransInt16(content,4));
agvData.setAlarm(byteTransform.TransInt16(content,6));
agvData.setStatus(byteTransform.TransInt16(content,8));
agvData.setFinish(byteTransform.TransInt16(content,10));
agvData.setChargeFlag(byteTransform.TransInt16(content,12));
agvData.setWorkPhase(byteTransform.TransInt16(content,14));
agvData.setErrorMsg(byteTransform.TransInt16(content,16));
agvData.setDeviceRequest(byteTransform.TransInt16(content,18));
agvData.setChangeLayer(byteTransform.TransInt16(content,20));
agvData.setCargoFlag(byteTransform.TransInt16(content,22));
agvData.setManualCharge(byteTransform.TransInt16(content,24));
agvData.setUndefined1(byteTransform.TransInt16(content,26));
agvData.setAllowSend(byteTransform.TransInt16(content,16));
}
private void setValueByByte2(byte[] content, DeviceSrgv agvData) {
byteTransform.setDataFormat(DataFormat.CDAB);
// TODO 注意双字反转
agvData.setTaskNo(byteTransform.TransInt32(content,0));
agvData.setSrcSite(String.format("%06d", byteTransform.TransInt32(content,4)));
agvData.setTarSite(String.format("%06d", byteTransform.TransInt32(content,8)));
agvData.setCurrSite(String.format("%06d", byteTransform.TransInt32(content,12)));
//设置库区
String currSite = agvData.getCurrSite();
String l = currSite.substring(2, 4);
int li = Integer.parseInt(l);//列
if(li<23){
agvData.setSpaceArea("01");
}else {
agvData.setSpaceArea("02");
}
//截取cur的后俩位,获取当前楼层
int floor = FloorUtils.extractFloor(Integer.parseInt(agvData.getCurrSite()));
this.layer = floor;
agvData.setCurrFloor(floor);
}
private void setValueByByte3(byte[] content, DeviceSrgv agvData) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < content.length; i += 4) {
// 检查剩余字节是否足够4个
if (i + 4 > content.length) break;
// TODO 注意双字反转
int value = byteTransform.TransInt32(content, i);
// 如果值为0,终止循环
if (value == 0) {
break;
}
sb.append(String.format("%06d", value)).append(","); // 用逗号分隔每个int值
}
// 移除最后多余的 ","
if (sb.length() > 0) {
sb.setLength(sb.length() - 1);
}
agvData.setPath(sb.toString());
}
public void ConnectServer(){
ModbusTcpNet modbusTcpNet = new ModbusTcpNet();//创建一个Modbus对象
try{
modbusTcpNet.setIpAddress(this.ip);
modbusTcpNet.setPort(this.port);
modbusTcpNet.setStation(station);
this.byteTransform=modbusTcpNet.getByteTransform();
OperateResult connect = modbusTcpNet.ConnectServer();
if (connect.IsSuccess) {
setIsConnect(true);
readWriteNet = modbusTcpNet;
}
}catch (Exception ex) {
log.info("********IP:" + this.ip + " port:" + this.port + "连接失败 " + ex.getMessage());
}
}
public void setIsConnect(boolean bflag) {
if (!success) {
success = bflag;
}
}
public boolean IsConnect() {
if (success) {
return success;
}
return false;
}
void reConnect() {
closeServer();
ConnectServer();
log.info("重新连接 SSJ-PLC");
}
void closeServer() {
if (readWriteNet != null) {
readWriteNet.ConnectClose();
}
setIsConnect(false);
}
}