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
1f857407
Commit
1f857407
authored
Sep 24, 2025
by
wanghao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1 测试 上电后通信 和 最终完成 定时任务功能
parent
bec4920b
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
216 additions
and
66 deletions
+216
-66
DeviceCommunicationJob.java
...n/java/com/zehong/system/task/DeviceCommunicationJob.java
+85
-27
FinalExecutionJob.java
...c/main/java/com/zehong/system/task/FinalExecutionJob.java
+131
-39
No files found.
zhmes-agecal-system/src/main/java/com/zehong/system/task/DeviceCommunicationJob.java
View file @
1f857407
package
com
.
zehong
.
system
.
task
;
import
com.zehong.system.domain.TEquipmentAlarmData
;
import
com.zehong.system.domain.TStoreyInfo
;
import
com.zehong.system.mapper.TStoreyInfoMapper
;
import
com.zehong.system.modbus.business.DeviceStatusReaderAndTimeSetter
;
import
com.zehong.system.modbus.handler.ModbusResultHandler
;
import
com.zehong.system.service.ITEquipmentAlarmDataService
;
import
org.apache.commons.lang3.StringUtils
;
import
org.quartz.Job
;
import
org.quartz.JobDataMap
;
import
org.quartz.JobExecutionContext
;
...
...
@@ -12,8 +14,10 @@ import org.slf4j.Logger;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
import
java.util.Arrays
;
import
java.util.Date
;
import
java.util.List
;
/**
...
...
@@ -37,37 +41,91 @@ public class DeviceCommunicationJob implements Job {
@Override
public
void
execute
(
JobExecutionContext
context
)
{
JobDataMap
data
=
context
.
getJobDetail
().
getJobDataMap
();
String
fStoreyId
=
data
.
getString
(
"fStoreyId"
);
log
.
info
(
"DeviceCommunicationJob.execute 的 fStoreyId:{}"
,
fStoreyId
);
long
l
=
Long
.
parseLong
(
fStoreyId
);
TStoreyInfo
tStoreyInfo
=
tStoreyInfoMapper
.
selectTStoreyInfoById
(
l
);
// 1. 初始化所有变量,避免空指针
JobDataMap
data
=
null
;
String
fStoreyIdStr
=
null
;
Long
fStoreyId
=
null
;
TStoreyInfo
tStoreyInfo
=
null
;
String
ip
=
null
;
try
{
// 1. 执行Modbus通信
String
s
=
tStoreyInfo
.
getfPort
();
String
ip
=
tStoreyInfo
.
getfIp
();
// 501 的 27个 设备id
List
<
Integer
>
registerOffsetsOne
=
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
);
// 501 对应 27个设备读取状态 并设置时间
deviceStatusReaderAndTimeSetter
.
startMultiDeviceMonitoring
(
ip
,
501
,
registerOffsetsOne
,
resultHandler
,
ModbusResultHandler
.
createDefaultStopCondition
());
// 2. 提取参数(每一步都校验,避免空指针)
data
=
context
.
getJobDetail
().
getJobDataMap
();
if
(
data
==
null
)
{
log
.
error
(
"JobDataMap为空,终止执行"
);
return
;
}
fStoreyIdStr
=
data
.
getString
(
"fStoreyId"
);
if
(
StringUtils
.
isBlank
(
fStoreyIdStr
))
{
log
.
error
(
"fStoreyId参数为空,终止执行"
);
return
;
}
// 3. 转换参数(处理NumberFormatException)
try
{
fStoreyId
=
Long
.
parseLong
(
fStoreyIdStr
);
}
catch
(
NumberFormatException
e
)
{
log
.
error
(
"fStoreyId格式错误:{},终止执行"
,
fStoreyIdStr
);
return
;
}
// 4. 查询设备信息(校验DB查询结果)
tStoreyInfo
=
tStoreyInfoMapper
.
selectTStoreyInfoById
(
fStoreyId
);
if
(
tStoreyInfo
==
null
)
{
log
.
error
(
"未查询到设备信息:fStoreyId={},终止执行"
,
fStoreyId
);
return
;
}
ip
=
tStoreyInfo
.
getfIp
();
if
(
StringUtils
.
isBlank
(
ip
))
{
log
.
error
(
"设备IP为空:fStoreyId={},终止执行"
,
fStoreyId
);
return
;
}
// 5. 执行Modbus通信(业务逻辑,每个调用都加try-catch)
List
<
Integer
>
offsets1
=
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
);
List
<
Integer
>
offsets2
=
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
);
List
<
Integer
>
offsets3
=
Arrays
.
asList
(
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
);
// 502 端口号的 27个 设备id
List
<
Integer
>
registerOffsetsTwo
=
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
);
// 502 对应 27个设备读取状态 并设置时间
deviceStatusReaderAndTimeSetter
.
startMultiDeviceMonitoring
(
ip
,
502
,
registerOffsetsTwo
,
resultHandler
,
ModbusResultHandler
.
createDefaultStopCondition
());
// 每个Modbus调用单独捕获异常,避免一个设备失败导致整个Job报错
try
{
deviceStatusReaderAndTimeSetter
.
startMultiDeviceMonitoring
(
ip
,
501
,
offsets1
,
resultHandler
,
ModbusResultHandler
.
createDefaultStopCondition
());
log
.
info
(
"Modbus 501端口通信完成:fStoreyId={}"
,
fStoreyId
);
}
catch
(
Exception
e
)
{
log
.
error
(
"Modbus 501端口通信异常:fStoreyId={}"
,
fStoreyId
,
e
);
// 仅记录日志,不抛出异常
}
try
{
deviceStatusReaderAndTimeSetter
.
startMultiDeviceMonitoring
(
ip
,
502
,
offsets2
,
resultHandler
,
ModbusResultHandler
.
createDefaultStopCondition
());
log
.
info
(
"Modbus 502端口通信完成:fStoreyId={}"
,
fStoreyId
);
}
catch
(
Exception
e
)
{
log
.
error
(
"Modbus 502端口通信异常:fStoreyId={}"
,
fStoreyId
,
e
);
}
try
{
deviceStatusReaderAndTimeSetter
.
startMultiDeviceMonitoring
(
ip
,
503
,
offsets3
,
resultHandler
,
ModbusResultHandler
.
createDefaultStopCondition
());
log
.
info
(
"Modbus 503端口通信完成:fStoreyId={}"
,
fStoreyId
);
}
catch
(
Exception
e
)
{
log
.
error
(
"Modbus 503端口通信异常:fStoreyId={}"
,
fStoreyId
,
e
);
}
// 503 端口号的 剩下的设备
List
<
Integer
>
registerOffsetsThree
=
Arrays
.
asList
(
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
);
// 503 对应 剩下设备读取状态 并设置时间
deviceStatusReaderAndTimeSetter
.
startMultiDeviceMonitoring
(
ip
,
503
,
registerOffsetsThree
,
resultHandler
,
ModbusResultHandler
.
createDefaultStopCondition
());
log
.
info
(
"=== DeviceCommunicationJob 执行成功:fStoreyId={} ==="
,
fStoreyId
);
}
catch
(
Exception
e
)
{
// 记录异常
TEquipmentAlarmData
alarmData
=
new
TEquipmentAlarmData
();
alarmData
.
setfAlarmType
(
"03"
);
// 老化层
alarmData
.
setfEquipmentCode
(
tStoreyInfo
.
getfStoreyCode
());
alarmData
.
setfAlarmData
(
"通信失败: "
+
e
.
getMessage
());
alarmDataService
.
insertTEquipmentAlarmData
(
alarmData
);
}
catch
(
Throwable
e
)
{
// 6. 捕获所有异常(包括Error,如NoClassDefFoundError)
log
.
error
(
"=== DeviceCommunicationJob 执行致命异常:fStoreyId={} ==="
,
fStoreyIdStr
,
e
);
// 记录告警(内部异常也不抛出,确保Job不传播任何错误)
try
{
if
(
tStoreyInfo
!=
null
&&
StringUtils
.
isNotBlank
(
tStoreyInfo
.
getfStoreyCode
()))
{
TEquipmentAlarmData
alarm
=
new
TEquipmentAlarmData
();
alarm
.
setfAlarmType
(
"03"
);
alarm
.
setfEquipmentCode
(
tStoreyInfo
.
getfStoreyCode
());
alarm
.
setfAlarmData
(
"通信任务异常:"
+
e
.
getMessage
());
alarm
.
setfCreateTime
(
new
Date
());
alarmDataService
.
insertTEquipmentAlarmData
(
alarm
);
}
}
catch
(
Exception
alarmEx
)
{
log
.
error
(
"=== 告警记录失败(不影响触发器) ==="
,
alarmEx
);
}
// 绝对禁止抛出任何异常!!!
}
}
}
zhmes-agecal-system/src/main/java/com/zehong/system/task/FinalExecutionJob.java
View file @
1f857407
...
...
@@ -46,49 +46,134 @@ public class FinalExecutionJob implements Job {
private
RobotArmCommandMapper
robotArmCommandMapper
;
@Override
public
void
execute
(
JobExecutionContext
context
)
{
JobDataMap
data
=
context
.
getJobDetail
().
getJobDataMap
();
String
fStoreyId
=
data
.
getString
(
"fStoreyId"
);
String
fPowerOutageIp
=
data
.
getString
(
"fPowerOutageIp"
);
String
fPowerOutagePort
=
data
.
getString
(
"fPowerOutagePort"
);
TStoreyInfo
tStoreyInfo
=
tStoreyInfoMapper
.
selectTStoreyInfoById
(
Long
.
parseLong
(
fStoreyId
));
if
(
tStoreyInfo
==
null
||
StringUtils
.
isBlank
(
fPowerOutagePort
)
||
StringUtils
.
isBlank
(
fPowerOutageIp
))
{
// 记录异常
TEquipmentAlarmData
alarmData
=
new
TEquipmentAlarmData
();
alarmData
.
setfAlarmType
(
"03"
);
// 老化层
alarmData
.
setfEquipmentCode
(
fStoreyId
);
alarmData
.
setfAlarmData
(
"71小时到老化层业务逻辑时数据丢失"
);
alarmDataService
.
insertTEquipmentAlarmData
(
alarmData
);
}
else
{
// 1. 初始化变量,避免空指针
JobDataMap
data
=
null
;
String
fStoreyIdStr
=
null
;
String
fPowerOutageIp
=
null
;
String
fPowerOutagePortStr
=
null
;
Long
fStoreyId
=
null
;
Integer
fPowerOutagePort
=
null
;
TStoreyInfo
tStoreyInfo
=
null
;
try
{
// 2. 提取并校验所有参数
data
=
context
.
getJobDetail
().
getJobDataMap
();
if
(
data
==
null
)
{
log
.
error
(
"JobDataMap为空,终止执行"
);
return
;
}
fStoreyIdStr
=
data
.
getString
(
"fStoreyId"
);
fPowerOutageIp
=
data
.
getString
(
"fPowerOutageIp"
);
fPowerOutagePortStr
=
data
.
getString
(
"fPowerOutagePort"
);
if
(
StringUtils
.
isAnyBlank
(
fStoreyIdStr
,
fPowerOutageIp
,
fPowerOutagePortStr
))
{
log
.
error
(
"参数缺失:fStoreyId={}, ip={}, port={},终止执行"
,
fStoreyIdStr
,
fPowerOutageIp
,
fPowerOutagePortStr
);
return
;
}
// 3. 参数格式转换(处理NumberFormatException)
try
{
log
.
info
(
"设备[{}]开始执行最终业务逻辑"
,
tStoreyInfo
.
getfStoreyCode
());
fStoreyId
=
Long
.
parseLong
(
fStoreyIdStr
);
fPowerOutagePort
=
Integer
.
parseInt
(
fPowerOutagePortStr
);
}
catch
(
NumberFormatException
e
)
{
log
.
error
(
"参数格式错误:fStoreyId={}, port={},终止执行"
,
fStoreyIdStr
,
fPowerOutagePortStr
);
return
;
}
// 1. 执行业务逻辑
String
s
=
tStoreyInfo
.
getfStoreyCode
().
split
(
"-"
)[
1
];
int
i
=
Integer
.
parseInt
(
s
);
executeBusinessLogic
(
fPowerOutageIp
,
Integer
.
parseInt
(
fPowerOutagePort
),(
i
-
1
));
// 4. 查询设备信息
tStoreyInfo
=
tStoreyInfoMapper
.
selectTStoreyInfoById
(
fStoreyId
);
if
(
tStoreyInfo
==
null
)
{
log
.
error
(
"未查询到设备信息:fStoreyId={},终止执行"
,
fStoreyId
);
return
;
}
// 2. 更新任务状态
// 5. 执行业务逻辑(Modbus写操作,单独捕获异常)
String
storeyCode
=
tStoreyInfo
.
getfStoreyCode
();
if
(
StringUtils
.
isBlank
(
storeyCode
))
{
log
.
error
(
"设备编码为空:fStoreyId={},终止执行"
,
fStoreyId
);
return
;
}
int
registerOffsets
;
try
{
registerOffsets
=
Integer
.
parseInt
(
storeyCode
.
split
(
"-"
)[
1
])
-
1
;
}
catch
(
Exception
e
)
{
log
.
error
(
"设备编码解析失败:storeyCode={},终止执行"
,
storeyCode
);
return
;
}
// Modbus写操作(容错:失败不影响后续清理任务)
try
{
executeBusinessLogic
(
fPowerOutageIp
,
fPowerOutagePort
,
registerOffsets
);
log
.
info
(
"Modbus写操作完成:fStoreyId={}"
,
fStoreyId
);
}
catch
(
Exception
e
)
{
log
.
error
(
"Modbus写操作异常:fStoreyId={}"
,
fStoreyId
,
e
);
// 记录告警,但不终止执行(后续清理任务必须执行)
recordAlarm
(
tStoreyInfo
,
"Modbus写操作失败:"
+
e
.
getMessage
());
}
// 6. 更新设备状态(DB操作单独捕获异常)
try
{
tStoreyInfo
.
setfStatus
(
"0"
);
tStoreyInfo
.
setfAgingStartTime
(
null
);
tStoreyInfoService
.
updateTStoreyInfo
(
tStoreyInfo
);
log
.
info
(
"设备状态更新完成:fStoreyId={}"
,
fStoreyId
);
}
catch
(
Exception
e
)
{
log
.
error
(
"设备状态更新异常:fStoreyId={}"
,
fStoreyId
,
e
);
recordAlarm
(
tStoreyInfo
,
"设备状态更新失败:"
+
e
.
getMessage
());
}
// 3. 清理相关任务
cleanUpJobs
(
fStoreyId
,
context
);
// 4. 发送 下料指令
createRoboticArm
(
tStoreyInfo
.
getfTrayCode
(),
tStoreyInfo
.
getfStoreyCode
(),
tStoreyInfo
.
getBlankingCommand
());
// 7. 清理任务(Quartz操作单独捕获异常)
try
{
cleanUpJobs
(
fStoreyId
,
context
);
log
.
info
(
"任务清理完成:fStoreyId={}"
,
fStoreyId
);
}
catch
(
Exception
e
)
{
log
.
error
(
"任务清理异常:fStoreyId={}"
,
fStoreyId
,
e
);
recordAlarm
(
tStoreyInfo
,
"任务清理失败:"
+
e
.
getMessage
());
}
log
.
info
(
"设备[{}]最终业务逻辑执行完成"
,
fStoreyId
);
// 8. 发送机械臂指令(单独捕获异常)
try
{
createRoboticArm
(
tStoreyInfo
.
getfTrayCode
(),
storeyCode
,
tStoreyInfo
.
getBlankingCommand
());
log
.
info
(
"机械臂指令发送完成:fStoreyId={}"
,
fStoreyId
);
}
catch
(
Exception
e
)
{
// 记录异常
TEquipmentAlarmData
alarmData
=
new
TEquipmentAlarmData
();
alarmData
.
setfAlarmType
(
"03"
);
// 老化层
alarmData
.
setfEquipmentCode
(
tStoreyInfo
.
getfStoreyCode
());
alarmData
.
setfAlarmData
(
"老化层清除任务时失败"
);
alarmDataService
.
insertTEquipmentAlarmData
(
alarmData
);
log
.
error
(
"机械臂指令发送异常:fStoreyId={}"
,
fStoreyId
,
e
);
recordAlarm
(
tStoreyInfo
,
"机械臂指令发送失败:"
+
e
.
getMessage
());
}
log
.
info
(
"=== FinalExecutionJob 执行完成:fStoreyId={} ==="
,
fStoreyId
);
}
catch
(
Throwable
e
)
{
// 9. 捕获所有异常(包括Error)
log
.
error
(
"=== FinalExecutionJob 致命异常:fStoreyId={} ==="
,
fStoreyIdStr
,
e
);
// 记录告警(即使设备信息为空,也尝试记录)
try
{
if
(
tStoreyInfo
!=
null
&&
StringUtils
.
isNotBlank
(
tStoreyInfo
.
getfStoreyCode
()))
{
recordAlarm
(
tStoreyInfo
,
"最终任务致命异常:"
+
e
.
getMessage
());
}
else
{
TEquipmentAlarmData
alarm
=
new
TEquipmentAlarmData
();
alarm
.
setfAlarmType
(
"03"
);
alarm
.
setfEquipmentCode
(
fStoreyIdStr
);
alarm
.
setfAlarmData
(
"最终任务致命异常:"
+
e
.
getMessage
());
alarm
.
setfCreateTime
(
new
Date
());
alarmDataService
.
insertTEquipmentAlarmData
(
alarm
);
}
}
catch
(
Exception
alarmEx
)
{
log
.
error
(
"=== 告警记录失败 ==="
,
alarmEx
);
}
// 禁止抛出任何异常!!!
}
}
// 辅助方法:记录告警(抽离,避免代码重复)
private
void
recordAlarm
(
TStoreyInfo
tStoreyInfo
,
String
alarmMsg
)
{
try
{
TEquipmentAlarmData
alarm
=
new
TEquipmentAlarmData
();
alarm
.
setfAlarmType
(
"03"
);
alarm
.
setfEquipmentCode
(
tStoreyInfo
.
getfStoreyCode
());
alarm
.
setfAlarmData
(
alarmMsg
);
alarm
.
setfCreateTime
(
new
Date
());
alarmDataService
.
insertTEquipmentAlarmData
(
alarm
);
log
.
info
(
"告警记录完成:{}"
,
tStoreyInfo
.
getfStoreyCode
());
}
catch
(
Exception
e
)
{
log
.
error
(
"告警记录失败:{}"
,
tStoreyInfo
.
getfStoreyCode
(),
e
);
}
}
...
...
@@ -105,12 +190,19 @@ public class FinalExecutionJob implements Job {
notifyCommandsUpdate
();
}
private
void
cleanUpJobs
(
String
deviceId
,
JobExecutionContext
context
)
throws
SchedulerException
{
// 删除通信任务
scheduler
.
deleteJob
(
new
JobKey
(
"COMM_"
+
deviceId
,
"DEVICE_TASKS"
));
// 删除自身任务
scheduler
.
deleteJob
(
context
.
getJobDetail
().
getKey
());
private
void
cleanUpJobs
(
Long
fStoreyId
,
JobExecutionContext
context
)
throws
SchedulerException
{
// 清理通信任务
JobKey
commJobKey
=
new
JobKey
(
"COMM_"
+
fStoreyId
,
"DEVICE_TASKS"
);
if
(
scheduler
.
checkExists
(
commJobKey
))
{
boolean
commDeleted
=
scheduler
.
deleteJob
(
commJobKey
);
log
.
info
(
"通信任务清理结果:{}({})"
,
commDeleted
?
"成功"
:
"失败"
,
commJobKey
.
getName
());
}
// 清理自身任务
JobKey
selfJobKey
=
context
.
getJobDetail
().
getKey
();
if
(
scheduler
.
checkExists
(
selfJobKey
))
{
boolean
selfDeleted
=
scheduler
.
deleteJob
(
selfJobKey
);
log
.
info
(
"自身任务清理结果:{}({})"
,
selfDeleted
?
"成功"
:
"失败"
,
selfJobKey
.
getName
());
}
}
// ... 业务逻辑方法
...
...
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