Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
Z
zhmes-agecal
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
耿迪迪
zhmes-agecal
Commits
b09d5a05
Commit
b09d5a05
authored
Sep 25, 2025
by
wanghao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1 指令指令完成,但是 没有检测到机械臂完成。
parent
d22727dd
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
201 additions
and
265 deletions
+201
-265
ModbusResultHandler.java
...com/zehong/system/modbus/handler/ModbusResultHandler.java
+3
-1
BaseDeviceCommJob.java
...c/main/java/com/zehong/system/task/BaseDeviceCommJob.java
+192
-176
DeviceComm501Device1Job.java
...ng/system/task/DeviceCommJob/DeviceComm501Device1Job.java
+2
-3
DeviceComm501Device2Job.java
...ng/system/task/DeviceCommJob/DeviceComm501Device2Job.java
+2
-3
DeviceComm501Device3Job.java
...ng/system/task/DeviceCommJob/DeviceComm501Device3Job.java
+2
-3
DeviceComm501Job.java
...om/zehong/system/task/DeviceCommJob/DeviceComm501Job.java
+0
-27
DeviceComm502Job.java
...om/zehong/system/task/DeviceCommJob/DeviceComm502Job.java
+0
-26
DeviceComm503Job.java
...om/zehong/system/task/DeviceCommJob/DeviceComm503Job.java
+0
-26
No files found.
zhmes-agecal-system/src/main/java/com/zehong/system/modbus/handler/ModbusResultHandler.java
View file @
b09d5a05
...
...
@@ -148,13 +148,16 @@ public class ModbusResultHandler implements Consumer<DeviceStatusReaderDto> {
}
catch
(
ModbusInitException
e
)
{
log
.
error
(
"Modbus初始化异常:ip={}, port={}"
,
ip
,
port
,
e
);
palletDeviceBinding
.
setStatus
(
"5"
);
recordAlarm
(
palletDeviceBinding
,
"Modbus初始化失败:"
+
e
.
getMessage
());
}
catch
(
ModbusTransportException
e
)
{
log
.
error
(
"Modbus传输异常:ip={}, port={}, deviceId={}"
,
ip
,
port
,
deviceId
,
e
);
palletDeviceBinding
.
setStatus
(
"5"
);
recordAlarm
(
palletDeviceBinding
,
"Modbus写时间失败:"
+
e
.
getMessage
());
}
catch
(
Exception
e
)
{
// 捕获其他异常(如NPE、数据溢出)
log
.
error
(
"处理Modbus数据异常:ip={}, port={}, deviceId={}"
,
ip
,
port
,
deviceId
,
e
);
palletDeviceBinding
.
setStatus
(
"5"
);
recordAlarm
(
palletDeviceBinding
,
"数据处理异常:"
+
e
.
getMessage
());
}
finally
{
// 关键:关闭Modbus连接,避免资源泄漏
...
...
@@ -300,7 +303,6 @@ public class ModbusResultHandler implements Consumer<DeviceStatusReaderDto> {
return
str
==
null
||
str
.
trim
().
isEmpty
();
}
}
// 创建通用的停止条件(可选)
public
static
Predicate
<
int
[]>
createDefaultStopCondition
()
{
return
values
->
values
.
length
>=
2
&&
values
[
1
]
==
DeviceStatusReaderAndTimeSetter
.
TARGET_VALUE
;
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/task/BaseDeviceCommJob.java
View file @
b09d5a05
package
com
.
zehong
.
system
.
task
;
import
org.quartz.Job
;
import
org.springframework.stereotype.Component
;
import
com.serotonin.modbus4j.ModbusFactory
;
import
com.serotonin.modbus4j.ModbusMaster
;
import
com.serotonin.modbus4j.exception.ModbusInitException
;
import
com.serotonin.modbus4j.exception.ModbusTransportException
;
import
com.serotonin.modbus4j.ip.IpParameters
;
import
com.serotonin.modbus4j.ip.tcp.TcpMaster
;
import
com.serotonin.modbus4j.msg.ModbusResponse
;
import
com.serotonin.modbus4j.msg.ReadHoldingRegistersRequest
;
import
com.serotonin.modbus4j.msg.ReadHoldingRegistersResponse
;
import
com.zehong.system.domain.PalletDeviceBinding
;
import
com.zehong.system.domain.TEquipmentAlarmData
;
import
com.zehong.system.domain.TStoreyInfo
;
import
com.zehong.system.mapper.PalletDeviceBindingMapper
;
import
com.zehong.system.mapper.TStoreyInfoMapper
;
import
com.zehong.system.modbus.handler.ModbusResultHandler
;
import
com.zehong.system.modbus.handler.dto.DeviceStatusReaderDto
;
...
...
@@ -32,8 +31,10 @@ import java.lang.reflect.Field;
import
java.net.Socket
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.concurrent.*
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.Future
;
import
java.util.concurrent.TimeUnit
;
import
java.util.function.Predicate
;
/**
* @author lenovo
...
...
@@ -44,15 +45,18 @@ import java.util.function.Predicate;
public
abstract
class
BaseDeviceCommJob
implements
Job
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
BaseDeviceCommJob
.
class
);
// -------------------------- 公共常量配置 --------------------------
private
static
final
int
TOTAL_TASK_TIMEOUT_SEC
=
240
;
// 任务总超时:4分钟
private
static
final
int
SINGLE_DEVICE_TIMEOUT_SEC
=
10
;
// 单个设备超时:10秒
private
static
final
int
MODBUS_CONN_TIMEOUT_MS
=
3000
;
// 连接超时:3秒
private
static
final
int
CUSTOM_RETRY_TIMES
=
1
;
// 自定义重试次数:1次
private
static
final
int
RETRY_DELAY_MS
=
200
;
// 重试间隔:200ms
// -------------------------- 核心常量(仅保留必要配置,删除冗余) --------------------------
// 超时配置:适配单设备场景,无需预留多设备缓冲
private
static
final
int
SINGLE_DEVICE_TIMEOUT_SEC
=
10
;
// 单个设备总超时
private
static
final
int
MODBUS_CONN_TIMEOUT_MS
=
3000
;
// Modbus连接超时
// 重试配置:单设备重试1次足够,避免过度占用连接
private
static
final
int
CUSTOM_RETRY_TIMES
=
3
;
private
static
final
int
RETRY_DELAY_MS
=
200
;
// Modbus寄存器固定配置(单设备无需动态调整)
private
static
final
int
REG_START_ADDR
=
0
;
private
static
final
int
REG_READ_COUNT
=
10
;
private
static
final
ModbusFactory
modbusFactory
=
new
ModbusFactory
();
// 单例工厂
// 单例Modbus工厂:避免重复创建开销
private
static
final
ModbusFactory
modbusFactory
=
new
ModbusFactory
();
// -------------------------- 公共依赖注入 --------------------------
@Resource
...
...
@@ -62,6 +66,9 @@ public abstract class BaseDeviceCommJob implements Job {
@Autowired
protected
ModbusResultHandler
resultHandler
;
@Resource
private
PalletDeviceBindingMapper
palletDeviceBindingMapper
;
// -------------------------- 抽象方法:子类实现差异化 --------------------------
/**
* 获取当前Job的固定端口号(501/502/503)
...
...
@@ -71,248 +78,247 @@ public abstract class BaseDeviceCommJob implements Job {
/**
* 获取当前端口对应的设备ID列表
*/
protected
abstract
List
<
Integer
>
getDeviceIds
();
protected
abstract
int
getDeviceId
();
// -------------------------- 核心执行逻辑(
公共
) --------------------------
// -------------------------- 核心执行逻辑(
单设备直连,无冗余步骤
) --------------------------
@Override
public
void
execute
(
JobExecutionContext
context
)
throws
JobExecutionException
{
public
void
execute
(
JobExecutionContext
context
)
{
long
taskStartTime
=
System
.
currentTimeMillis
();
String
storeyIdStr
=
getStoreyIdFromContext
(
context
);
ExecutorService
deviceExecutor
=
null
;
// 单设备场景:直接获取唯一deviceId(子类返回的List仅1个元素)
Integer
deviceId
=
getSingleDeviceId
();
TStoreyInfo
storeyInfo
=
null
;
try
{
// 1. 初始化线程池(单个端口设备数较少,核心线程数设为5)
deviceExecutor
=
new
ThreadPoolExecutor
(
5
,
5
,
0
,
TimeUnit
.
SECONDS
,
new
LinkedBlockingQueue
<>(
30
),
r
->
new
Thread
(
r
,
"modbus-port-"
+
getFixedPort
()
+
"-"
+
storeyIdStr
),
new
ThreadPoolExecutor
.
AbortPolicy
()
);
log
.
info
(
"单设备任务开始:port={}, deviceId={}, storeyId={}"
,
getFixedPort
(),
deviceId
,
storeyIdStr
);
//
2. 执行当前端口的设备通信(带总超时
)
executePortDevices
(
context
,
deviceExecutor
,
taskStartTime
,
storeyIdStr
);
//
1. 校验基础参数(设备信息、IP、端口
)
storeyInfo
=
validateBaseParams
(
storeyIdStr
);
log
.
info
(
"端口[{}]通信任务执行成功:fStoreyId={},总耗时={}ms"
,
getFixedPort
(),
storeyIdStr
,
System
.
currentTimeMillis
()
-
taskStartTime
);
}
catch
(
Throwable
e
)
{
String
errMsg
=
"端口["
+
getFixedPort
()
+
"]通信任务异常:fStoreyId="
+
storeyIdStr
;
log
.
error
(
errMsg
,
e
);
recordAlarm
(
null
,
storeyIdStr
,
errMsg
+
":"
+
e
.
getMessage
());
throw
new
JobExecutionException
(
errMsg
,
e
);
// 抛出让Quartz感知,不隐藏异常
}
finally
{
// 3. 强制关闭线程池,避免资源泄漏
if
(
deviceExecutor
!=
null
&&
!
deviceExecutor
.
isShutdown
())
{
deviceExecutor
.
shutdownNow
();
try
{
if
(!
deviceExecutor
.
awaitTermination
(
5
,
TimeUnit
.
SECONDS
))
{
log
.
warn
(
"端口[{}]线程池关闭超时:fStoreyId={}"
,
getFixedPort
(),
storeyIdStr
);
}
}
catch
(
InterruptedException
e
)
{
log
.
warn
(
"端口[{}]线程池关闭被中断:fStoreyId={}"
,
getFixedPort
(),
storeyIdStr
);
}
if
(
storeyInfo
==
null
)
{
log
.
info
(
"设备不存在:fStoreyId={}"
,
storeyIdStr
);
return
;
}
}
}
/**
* 执行当前端口的所有设备通信(带总超时)
*/
private
void
executePortDevices
(
JobExecutionContext
context
,
ExecutorService
deviceExecutor
,
long
taskStartTime
,
String
storeyIdStr
)
throws
Exception
{
// 校验设备信息
TStoreyInfo
storeyInfo
=
validateAndGetStoreyInfo
(
storeyIdStr
);
String
ip
=
storeyInfo
.
getfIp
();
String
deviceIp
=
storeyInfo
.
getfIp
();
int
port
=
getFixedPort
();
List
<
Integer
>
deviceIds
=
getDeviceIds
();
// 设备通信计数器
CountDownLatch
deviceLatch
=
new
CountDownLatch
(
deviceIds
.
size
());
AtomicInteger
deviceErrorCount
=
new
AtomicInteger
(
0
);
// 2. 执行单设备Modbus通信(带超时+重试)
int
[]
modbusResult
=
executeModbusWithTimeout
(
deviceIp
,
port
,
deviceId
);
// 逐个设备提交任务
for
(
int
deviceId
:
deviceIds
)
{
deviceExecutor
.
submit
(()
->
{
try
{
executeSingleDeviceWithTimeout
(
ip
,
port
,
deviceId
,
storeyIdStr
);
}
catch
(
Exception
e
)
{
deviceErrorCount
.
incrementAndGet
();
log
.
error
(
"端口[{}]设备[{}]通信异常:fStoreyId={}"
,
port
,
deviceId
,
storeyIdStr
,
e
);
recordAlarm
(
storeyInfo
,
"设备"
+
deviceId
+
"通信异常:"
+
e
.
getMessage
());
}
finally
{
deviceLatch
.
countDown
();
}
});
// 3. 处理Modbus结果(非必须,为空则跳过)
if
(
resultHandler
!=
null
&&
modbusResult
!=
null
)
{
resultHandler
.
accept
(
new
DeviceStatusReaderDto
(
deviceIp
,
port
,
deviceId
,
modbusResult
));
}
else
{
updateDeviceError
(
storeyInfo
.
getfIp
());
}
// 等待所有设备完成(带总超时)
boolean
allCompleted
=
deviceLatch
.
await
(
TOTAL_TASK_TIMEOUT_SEC
,
TimeUnit
.
SECONDS
);
long
totalCost
=
System
.
currentTimeMillis
()
-
taskStartTime
;
log
.
info
(
"单设备任务成功:port={}, deviceId={}, storeyId={},耗时={}ms"
,
port
,
deviceId
,
storeyIdStr
,
System
.
currentTimeMillis
()
-
taskStartTime
);
// 超时校验
if
(
totalCost
>
TOTAL_TASK_TIMEOUT_SEC
*
1000
)
{
String
errMsg
=
"端口["
+
port
+
"]任务总超时:fStoreyId="
+
storeyIdStr
+
",耗时="
+
totalCost
+
"ms"
;
log
.
warn
(
errMsg
);
recordAlarm
(
storeyInfo
,
errMsg
);
}
catch
(
Throwable
e
)
{
// 单设备异常直接捕获,记录告警并抛出让Quartz感知
String
errMsg
=
String
.
format
(
"单设备任务失败:port=%d, deviceId=%d, storeyId=%s"
,
getFixedPort
(),
deviceId
,
storeyIdStr
);
log
.
info
(
errMsg
,
e
);
if
(
storeyInfo
!=
null
)
{
updateDeviceError
(
storeyInfo
.
getfIp
());
}
// 错误统计
if
(
deviceErrorCount
.
get
()
>
0
)
{
String
errMsg
=
"端口["
+
port
+
"]"
+
deviceErrorCount
.
get
()
+
"个设备通信失败:fStoreyId="
+
storeyIdStr
;
log
.
error
(
errMsg
);
recordAlarm
(
storeyInfo
,
errMsg
);
recordAlarm
(
storeyInfo
,
storeyIdStr
,
errMsg
+
":"
+
e
.
getMessage
());
}
}
// -------------------------- 以下为原DeviceCommunicationJob的公共工具方法 --------------------------
protected
TStoreyInfo
validateAndGetStoreyInfo
(
String
storeyIdStr
)
{
if
(
StringUtils
.
isBlank
(
storeyIdStr
))
{
String
errMsg
=
"fStoreyId为空:端口["
+
getFixedPort
()
+
"]"
;
log
.
error
(
errMsg
);
recordAlarm
(
null
,
"unknown"
,
errMsg
);
throw
new
RuntimeException
(
errMsg
);
// -------------------------- 精简后的核心工具方法 --------------------------
/**
* 提取单个deviceId(子类返回的List仅1个元素,避免集合遍历)
*/
private
Integer
getSingleDeviceId
()
{
return
getDeviceId
();
}
Long
storeyId
;
try
{
storeyId
=
Long
.
parseLong
(
storeyIdStr
);
}
catch
(
NumberFormatException
e
)
{
String
errMsg
=
"fStoreyId格式错误:"
+
storeyIdStr
+
",端口["
+
getFixedPort
()
+
"]"
;
log
.
error
(
errMsg
);
recordAlarm
(
null
,
storeyIdStr
,
errMsg
);
throw
new
RuntimeException
(
errMsg
);
/**
* 校验基础参数(storeyId、设备信息、IP),失败直接抛异常
*/
private
TStoreyInfo
validateBaseParams
(
String
storeyIdStr
)
{
// 1. 校验storeyId格式
if
(
StringUtils
.
isBlank
(
storeyIdStr
))
{
log
.
info
(
"storeyId为空:port="
+
getFixedPort
());
}
Long
storeyId
=
parseStoreyId
(
storeyIdStr
);
if
(
storeyId
==
null
)
{
log
.
info
(
"storeyId格式错误:port="
+
getFixedPort
());
return
null
;
}
// 2. 校验设备信息和IP
TStoreyInfo
storeyInfo
=
tStoreyInfoMapper
.
selectTStoreyInfoById
(
storeyId
);
if
(
storeyInfo
==
null
||
StringUtils
.
isBlank
(
storeyInfo
.
getfIp
()))
{
String
errMsg
=
"设备信息无效:fStoreyId="
+
storeyId
+
",端口["
+
getFixedPort
()
+
"]"
;
log
.
error
(
errMsg
);
recordAlarm
(
null
,
storeyIdStr
,
errMsg
);
throw
new
RuntimeException
(
errMsg
);
log
.
info
(
"设备信息无效:storeyId="
+
storeyId
);
}
return
storeyInfo
;
}
protected
void
executeSingleDeviceWithTimeout
(
String
ip
,
int
port
,
int
deviceId
,
String
storeyIdStr
)
{
Future
<?>
deviceFuture
=
Executors
.
newSingleThreadExecutor
().
submit
(()
->
{
/**
* 解析storeyId(单独抽离,减少代码冗余)
*/
private
Long
parseStoreyId
(
String
storeyIdStr
)
{
try
{
int
[]
result
=
readDeviceWithRetry
(
ip
,
port
,
deviceId
,
storeyIdStr
);
if
(
resultHandler
!=
null
)
{
resultHandler
.
accept
(
new
DeviceStatusReaderDto
(
ip
,
port
,
deviceId
,
result
));
return
Long
.
parseLong
(
storeyIdStr
);
}
catch
(
NumberFormatException
e
)
{
log
.
info
(
"设备信息无效:storeyId="
+
storeyIdStr
);
}
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"设备["
+
deviceId
+
"]读取失败"
,
e
);
return
null
;
}
});
/**
* 单设备Modbus通信(带超时+重试,无线程池,用Future做超时控制)
*/
private
int
[]
executeModbusWithTimeout
(
String
ip
,
int
port
,
int
deviceId
)
throws
Exception
{
// 用单线程池做超时控制(比自定义线程更轻量,执行完自动销毁)
ExecutorService
singleExecutor
=
Executors
.
newSingleThreadExecutor
();
try
{
deviceFuture
.
get
(
SINGLE_DEVICE_TIMEOUT_SEC
,
TimeUnit
.
SECONDS
);
}
catch
(
TimeoutException
e
)
{
deviceFuture
.
cancel
(
true
);
throw
new
RuntimeException
(
"设备["
+
deviceId
+
"]通信超时(>"
+
SINGLE_DEVICE_TIMEOUT_SEC
+
"秒)"
);
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"设备["
+
deviceId
+
"]通信异常"
,
e
.
getCause
());
Future
<
int
[]>
future
=
singleExecutor
.
submit
(()
->
readModbusWithRetry
(
ip
,
port
,
deviceId
)
);
// 超时控制:超过SINGLE_DEVICE_TIMEOUT_SEC秒直接中断
return
future
.
get
(
SINGLE_DEVICE_TIMEOUT_SEC
,
TimeUnit
.
SECONDS
);
}
finally
{
// 强制关闭线程池,避免资源泄漏(单线程池关闭开销极小)
singleExecutor
.
shutdownNow
();
}
}
protected
int
[]
readDeviceWithRetry
(
String
ip
,
int
port
,
int
deviceId
,
String
storeyIdStr
)
throws
Exception
{
/**
* Modbus读取(带重试,连接用完即时销毁)
*/
private
int
[]
readModbusWithRetry
(
String
ip
,
int
port
,
int
deviceId
)
throws
Exception
{
ModbusMaster
master
=
null
;
int
[]
result
=
null
;
for
(
int
retry
=
0
;
retry
<=
CUSTOM_RETRY_TIMES
;
retry
++)
{
try
{
// 1. 创建Modbus连接(禁用内置重试,避免冲突)
master
=
createModbusMaster
(
ip
,
port
);
result
=
readDeviceRegisters
(
master
,
deviceId
);
Predicate
<
int
[]>
stopCondition
=
ModbusResultHandler
.
createDefaultStopCondition
();
if
(
stopCondition
.
test
(
result
))
{
log
.
debug
(
"端口[{}]设备[{}]读取成功:重试={},fStoreyId={}"
,
port
,
deviceId
,
retry
,
storeyIdStr
);
break
;
}
else
if
(
retry
<
CUSTOM_RETRY_TIMES
)
{
Thread
.
sleep
(
RETRY_DELAY_MS
);
// 2. 读取寄存器
int
[]
result
=
readRegisters
(
master
,
deviceId
);
// 3. 校验结果(满足停止条件则返回,否则重试)
if
(
isValidResult
(
result
))
{
log
.
info
(
"Modbus读取成功:retry={}, port={}, deviceId={}"
,
retry
,
port
,
deviceId
);
return
result
;
}
log
.
info
(
"Modbus结果不满足条件,重试:retry={}, port={}, deviceId={}"
,
retry
,
port
,
deviceId
);
}
catch
(
Exception
e
)
{
// 重试耗尽才抛异常
if
(
retry
>=
CUSTOM_RETRY_TIMES
)
{
log
.
error
(
"端口[{}]设备[{}]重试耗尽({}次):fStoreyId={}"
,
port
,
deviceId
,
CUSTOM_RETRY_TIMES
,
storeyIdStr
,
e
);
throw
e
;
throw
new
RuntimeException
(
String
.
format
(
"Modbus重试耗尽(%d次):ip=%s, port=%d, deviceId=%d"
,
CUSTOM_RETRY_TIMES
,
ip
,
port
,
deviceId
),
e
);
}
Thread
.
sleep
(
RETRY_DELAY_MS
);
log
.
info
(
"Modbus读取异常,重试:retry={}, port={}, deviceId={}"
,
retry
,
port
,
deviceId
,
e
);
}
finally
{
// 每次重试后销毁连接(关键:避免单设备场景下的连接泄漏)
destroyModbusMaster
(
master
,
deviceId
);
// 重试间隔(最后一次重试无需等)
if
(
retry
<
CUSTOM_RETRY_TIMES
)
{
Thread
.
sleep
(
RETRY_DELAY_MS
);
}
}
return
result
;
}
log
.
info
(
"Modbus读取无有效结果:ip="
+
ip
+
", port="
+
port
+
", deviceId="
+
deviceId
);
return
null
;
}
protected
ModbusMaster
createModbusMaster
(
String
ip
,
int
port
)
throws
ModbusInitException
{
// -------------------------- Modbus基础操作(保留核心,精简冗余) --------------------------
/**
* 创建Modbus Master(无冗余配置,仅核心参数)
*/
private
ModbusMaster
createModbusMaster
(
String
ip
,
int
port
)
throws
ModbusInitException
{
IpParameters
params
=
new
IpParameters
();
params
.
setHost
(
ip
);
params
.
setPort
(
port
);
TcpMaster
master
=
(
TcpMaster
)
modbusFactory
.
createTcpMaster
(
params
,
true
);
master
.
setTimeout
(
MODBUS_CONN_TIMEOUT_MS
);
master
.
setRetries
(
0
);
// 禁用内置重试,用自定义重试
master
.
setRetries
(
0
);
// 禁用内置重试,用自定义重试
逻辑
master
.
init
();
return
master
;
}
protected
int
[]
readDeviceRegisters
(
ModbusMaster
master
,
int
deviceId
)
throws
ModbusTransportException
{
/**
* 读取寄存器(无冗余判断,直接强转)
*/
private
int
[]
readRegisters
(
ModbusMaster
master
,
int
deviceId
)
throws
ModbusTransportException
{
ReadHoldingRegistersRequest
request
=
Modbus4jUtils
.
getReadHoldingRegistersRequest
(
deviceId
,
REG_START_ADDR
,
REG_READ_COUNT
);
ModbusResponse
response
=
master
.
send
(
request
);
if
(!(
response
instanceof
ReadHoldingRegistersResponse
))
{
throw
new
RuntimeException
(
"无效Modbus响应:设备["
+
deviceId
+
"]"
);
}
short
[]
signedVals
=
((
ReadHoldingRegistersResponse
)
response
).
getShortData
();
ReadHoldingRegistersResponse
response
=
(
ReadHoldingRegistersResponse
)
master
.
send
(
request
);
// 转换为无符号整数(单设备场景无需循环优化,直接遍历)
short
[]
signedVals
=
response
.
getShortData
();
int
[]
unsignedVals
=
new
int
[
signedVals
.
length
];
for
(
int
i
=
0
;
i
<
signedVals
.
length
;
i
++)
{
unsignedVals
[
i
]
=
signedVals
[
i
]
&
0xFFFF
;
// 转无符号整数
unsignedVals
[
i
]
=
signedVals
[
i
]
&
0xFFFF
;
}
return
unsignedVals
;
}
protected
void
destroyModbusMaster
(
ModbusMaster
master
,
int
deviceId
)
{
/**
* 销毁Modbus连接(精简反射逻辑,失败仅日志告警,不中断主流程)
*/
private
void
destroyModbusMaster
(
ModbusMaster
master
,
int
deviceId
)
{
if
(
master
==
null
)
return
;
try
{
// 1. 关闭底层Socket(反射失败不抛异常,避免影响主流程)
if
(
master
instanceof
TcpMaster
)
{
Socket
socket
=
getUnderlyingSocket
((
TcpMaster
)
master
);
if
(
socket
!=
null
&&
!
socket
.
isClosed
())
{
socket
.
close
();
closeSocket
((
TcpMaster
)
master
,
deviceId
);
}
}
}
catch
(
Exception
e
)
{
log
.
error
(
"设备[{}]Socket销毁异常"
,
deviceId
,
e
);
}
finally
{
// 2. 销毁Master
try
{
master
.
destroy
();
}
catch
(
Exception
e
)
{
log
.
error
(
"设备[{}]ModbusMaster销毁异常"
,
deviceId
,
e
);
}
log
.
info
(
"ModbusMaster销毁异常:deviceId={}"
,
deviceId
,
e
);
}
}
private
Socket
getUnderlyingSocket
(
TcpMaster
tcpMaster
)
{
/**
* 关闭底层Socket(精简反射代码,减少异常处理层级)
*/
private
void
closeSocket
(
TcpMaster
tcpMaster
,
int
deviceId
)
{
try
{
Field
socketField
=
TcpMaster
.
class
.
getDeclaredField
(
"socket"
);
socketField
.
setAccessible
(
true
);
return
(
Socket
)
socketField
.
get
(
tcpMaster
);
Socket
socket
=
(
Socket
)
socketField
.
get
(
tcpMaster
);
if
(
socket
!=
null
&&
!
socket
.
isClosed
())
{
socket
.
close
();
}
}
catch
(
Exception
e
)
{
log
.
warn
(
"反射获取Socket失败:TcpMaster版本不匹配"
,
e
);
return
null
;
log
.
info
(
"Modbus Socket关闭异常:deviceId={}"
,
deviceId
,
e
);
}
}
protected
String
getStoreyIdFromContext
(
JobExecutionContext
context
)
{
// -------------------------- 保留的基础工具方法(仅核心) --------------------------
/**
* 校验Modbus结果有效性(调用ResultHandler的停止条件,避免重复逻辑)
*/
private
boolean
isValidResult
(
int
[]
result
)
{
if
(
result
==
null
||
result
.
length
==
0
)
{
return
false
;
}
Predicate
<
int
[]>
stopCondition
=
ModbusResultHandler
.
createDefaultStopCondition
();
return
stopCondition
.
test
(
result
);
}
/**
* 从JobContext获取storeyId(精简异常处理,失败返回unknown)
*/
private
String
getStoreyIdFromContext
(
JobExecutionContext
context
)
{
try
{
return
context
.
getJobDetail
().
getJobDataMap
().
getString
(
"fStoreyId"
);
}
catch
(
Exception
e
)
{
log
.
error
(
"获取fS
toreyId失败"
,
e
);
log
.
info
(
"获取s
toreyId失败"
,
e
);
return
"unknown"
;
}
}
/**
* 记录告警(保留原逻辑,精简参数判断)
*/
protected
void
recordAlarm
(
TStoreyInfo
storeyInfo
,
String
equipmentCode
,
String
alarmData
)
{
try
{
TEquipmentAlarmData
alarm
=
new
TEquipmentAlarmData
();
...
...
@@ -322,11 +328,21 @@ public abstract class BaseDeviceCommJob implements Job {
alarm
.
setfCreateTime
(
new
Date
());
alarmDataService
.
insertTEquipmentAlarmData
(
alarm
);
}
catch
(
Exception
e
)
{
log
.
error
(
"告警记录失败:{}"
,
alarmData
,
e
);
log
.
info
(
"告警记录失败:{}"
,
alarmData
,
e
);
}
}
protected
void
recordAlarm
(
TStoreyInfo
storeyInfo
,
String
alarmData
)
{
recordAlarm
(
storeyInfo
,
storeyInfo
!=
null
?
storeyInfo
.
getfStoreyCode
()
:
"unknown"
,
alarmData
);
protected
void
updateDeviceError
(
String
ip
)
{
int
deviceId
=
getDeviceId
();
// 2. 查询数据库并校验(避免NPE)
PalletDeviceBinding
palletDeviceBinding
;
try
{
palletDeviceBinding
=
palletDeviceBindingMapper
.
selectByTrayIdAndIndex
(
ip
,
deviceId
);
if
(
palletDeviceBinding
!=
null
)
{
palletDeviceBinding
.
setStatus
(
"4"
);
}
}
catch
(
Exception
e
)
{
log
.
info
(
"查询PalletDeviceBinding异常:ip={}, deviceId={}"
,
ip
,
deviceId
,
e
);
}
}
}
zhmes-agecal-system/src/main/java/com/zehong/system/task/DeviceCommJob/DeviceComm501Device1Job.java
View file @
b09d5a05
...
...
@@ -21,8 +21,7 @@ public class DeviceComm501Device1Job extends BaseDeviceCommJob {
}
@Override
protected
List
<
Integer
>
getDeviceIds
()
{
// 端口501对应的设备ID列表
return
Collections
.
singletonList
(
1
);
protected
int
getDeviceId
()
{
return
1
;
}
}
zhmes-agecal-system/src/main/java/com/zehong/system/task/DeviceCommJob/DeviceComm501Device2Job.java
View file @
b09d5a05
...
...
@@ -20,8 +20,7 @@ public class DeviceComm501Device2Job extends BaseDeviceCommJob {
}
@Override
protected
List
<
Integer
>
getDeviceIds
()
{
// 端口501对应的设备ID列表
return
Collections
.
singletonList
(
2
);
protected
int
getDeviceId
()
{
return
2
;
}
}
zhmes-agecal-system/src/main/java/com/zehong/system/task/DeviceCommJob/DeviceComm501Device3Job.java
View file @
b09d5a05
...
...
@@ -20,8 +20,7 @@ public class DeviceComm501Device3Job extends BaseDeviceCommJob {
}
@Override
protected
List
<
Integer
>
getDeviceIds
()
{
// 端口501对应的设备ID列表
return
Collections
.
singletonList
(
3
);
protected
int
getDeviceId
()
{
return
3
;
}
}
zhmes-agecal-system/src/main/java/com/zehong/system/task/DeviceCommJob/DeviceComm501Job.java
deleted
100644 → 0
View file @
d22727dd
package
com
.
zehong
.
system
.
task
.
DeviceCommJob
;
import
com.zehong.system.task.BaseDeviceCommJob
;
import
org.springframework.stereotype.Component
;
import
java.util.Arrays
;
import
java.util.List
;
/**
* @author lenovo
* @date 2025/9/25
* @description TODO
*/
@Component
public
class
DeviceComm501Job
extends
BaseDeviceCommJob
{
@Override
protected
int
getFixedPort
()
{
return
501
;
// 固定端口501
}
@Override
protected
List
<
Integer
>
getDeviceIds
()
{
// 端口501对应的设备ID列表
return
Arrays
.
asList
(
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
);
}
}
zhmes-agecal-system/src/main/java/com/zehong/system/task/DeviceCommJob/DeviceComm502Job.java
deleted
100644 → 0
View file @
d22727dd
package
com
.
zehong
.
system
.
task
.
DeviceCommJob
;
import
com.zehong.system.task.BaseDeviceCommJob
;
import
org.springframework.stereotype.Component
;
import
java.util.Arrays
;
import
java.util.List
;
/**
* @author lenovo
* @date 2025/9/25
* @description TODO
*/
@Component
public
class
DeviceComm502Job
extends
BaseDeviceCommJob
{
@Override
protected
int
getFixedPort
()
{
return
502
;
// 固定端口502
}
@Override
protected
List
<
Integer
>
getDeviceIds
()
{
// 端口502对应的设备ID列表
return
Arrays
.
asList
(
28
,
29
,
30
,
31
,
32
,
33
,
34
,
35
,
36
,
37
,
38
,
39
,
40
,
41
,
42
,
43
,
44
,
45
,
46
,
47
,
48
,
49
,
50
,
51
,
52
,
53
,
54
);
}
}
zhmes-agecal-system/src/main/java/com/zehong/system/task/DeviceCommJob/DeviceComm503Job.java
deleted
100644 → 0
View file @
d22727dd
package
com
.
zehong
.
system
.
task
.
DeviceCommJob
;
import
com.zehong.system.task.BaseDeviceCommJob
;
import
org.springframework.stereotype.Component
;
import
java.util.Arrays
;
import
java.util.List
;
/**
* @author lenovo
* @date 2025/9/25
* @description TODO
*/
@Component
public
class
DeviceComm503Job
extends
BaseDeviceCommJob
{
@Override
protected
int
getFixedPort
()
{
return
503
;
// 固定端口503
}
@Override
protected
List
<
Integer
>
getDeviceIds
()
{
// 端口503对应的设备ID列表
return
Arrays
.
asList
(
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment