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
79410fee
Commit
79410fee
authored
Dec 06, 2025
by
wanghao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1 点数数据表 增加 继电器状态 等五个字段 DDL维护。
2 点位数据vo及历史记录vo 及mapper增加 继电器状态 等五个字段。 3 老化最终流程 执行 读取 继电器状态 等5个状态的 操作,待跟硬件对接。
parent
98287cc1
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
694 additions
and
332 deletions
+694
-332
addSql.sql
sql/addSql.sql
+18
-1
MesDeviceDomain.java
...c/main/java/com/zehong/system/domain/MesDeviceDomain.java
+77
-0
PalletDeviceBinding.java
...in/java/com/zehong/system/domain/PalletDeviceBinding.java
+118
-10
PalletDeviceUploadHistory.java
...a/com/zehong/system/domain/PalletDeviceUploadHistory.java
+113
-27
PalletDeviceBindingMapper.java
...a/com/zehong/system/mapper/PalletDeviceBindingMapper.java
+2
-2
Modbus4jUtils.java
...ain/java/com/zehong/system/modbus/util/Modbus4jUtils.java
+85
-14
CalibrationResultEventHandler.java
...ong/system/netty/event/CalibrationResultEventHandler.java
+15
-0
DeviceCommunicationJob.java
...n/java/com/zehong/system/task/DeviceCommunicationJob.java
+10
-128
FinalExecutionJob.java
...c/main/java/com/zehong/system/task/FinalExecutionJob.java
+136
-7
PrepareFinalExecutionJob.java
...java/com/zehong/system/task/PrepareFinalExecutionJob.java
+15
-134
PalletDeviceBindingMapper.xml
...ain/resources/mapper/system/PalletDeviceBindingMapper.xml
+55
-6
PalletDeviceUploadHistoryMapper.xml
...sources/mapper/system/PalletDeviceUploadHistoryMapper.xml
+50
-3
No files found.
sql/addSql.sql
View file @
79410fee
...
@@ -23,3 +23,20 @@ http://36.138.180.82:8087/mes/pcba/devices/acceptAgingCalibrationResults
...
@@ -23,3 +23,20 @@ http://36.138.180.82:8087/mes/pcba/devices/acceptAgingCalibrationResults
"recordMinute"
:
"14"
"recordMinute"
:
"14"
}
}
]
]
ALTER
TABLE
`t_pallet_device_binding`
ADD
COLUMN
`f_write_self_check_status`
INT
(
16
)
DEFAULT
NULL
COMMENT
'写入自检状态(可以是空,0-失败,1-成功)'
,
ADD
COLUMN
`f_relay_status`
INT
(
16
)
DEFAULT
NULL
COMMENT
'继电器状态(0-初始,1-动作)'
,
ADD
COLUMN
`f_pulse_status`
INT
(
16
)
DEFAULT
NULL
COMMENT
'脉冲状态(0-初始,1-动作)'
,
ADD
COLUMN
`f_module_status`
INT
(
16
)
DEFAULT
NULL
COMMENT
'模组状态(0-异常,1-正常)'
,
ADD
COLUMN
`f_sim_card_status`
INT
(
16
)
DEFAULT
NULL
COMMENT
'SIM卡状态(0-异常,1-正常)'
,
ADD
COLUMN
`f_network_status`
INT
(
16
)
DEFAULT
NULL
COMMENT
'网络状态(0-异常,1-正常)'
;
ALTER
TABLE
`t_pallet_device_upload_history`
ADD
COLUMN
`f_write_self_check_status`
INT
(
16
)
DEFAULT
NULL
COMMENT
'写入自检状态(可以是空,0-失败,1-成功)'
,
ADD
COLUMN
`f_relay_status`
INT
(
16
)
DEFAULT
NULL
COMMENT
'继电器状态(0-初始,1-动作)'
,
ADD
COLUMN
`f_pulse_status`
INT
(
16
)
DEFAULT
NULL
COMMENT
'脉冲状态(0-初始,1-动作)'
,
ADD
COLUMN
`f_module_status`
INT
(
16
)
DEFAULT
NULL
COMMENT
'模组状态(0-异常,1-正常)'
,
ADD
COLUMN
`f_sim_card_status`
INT
(
16
)
DEFAULT
NULL
COMMENT
'SIM卡状态(0-异常,1-正常)'
,
ADD
COLUMN
`f_network_status`
INT
(
16
)
DEFAULT
NULL
COMMENT
'网络状态(0-异常,1-正常)'
;
\ No newline at end of file
zhmes-agecal-system/src/main/java/com/zehong/system/domain/MesDeviceDomain.java
View file @
79410fee
...
@@ -98,6 +98,35 @@ public class MesDeviceDomain extends BaseEntity {
...
@@ -98,6 +98,35 @@ public class MesDeviceDomain extends BaseEntity {
*/
*/
private
String
calibrationConcentrationStatus
;
private
String
calibrationConcentrationStatus
;
/**
* 写自检状态 空 是没写 0-失败;1-成功
*/
private
Integer
writeSelfCheckStatus
;
/**
* 继电器状态 0:初始 1:动作
*/
private
Integer
relayStatus
;
/**
* 脉冲状态 0:初始 1:动作
*/
private
Integer
pulseStatus
;
/**
* 模块状态 0:异常 1:正常
*/
private
Integer
moduleStatus
;
/**
* SIM卡状态 0:异常 1:正常
*/
private
Integer
simCardStatus
;
/**
* 网络状态 0:异常 1:正常
*/
private
Integer
networkStatus
;
public
String
getMotherboardCode
()
{
public
String
getMotherboardCode
()
{
return
motherboardCode
;
return
motherboardCode
;
}
}
...
@@ -241,4 +270,52 @@ public class MesDeviceDomain extends BaseEntity {
...
@@ -241,4 +270,52 @@ public class MesDeviceDomain extends BaseEntity {
public
void
setRunTimeStatus
(
String
runTimeStatus
)
{
public
void
setRunTimeStatus
(
String
runTimeStatus
)
{
this
.
runTimeStatus
=
runTimeStatus
;
this
.
runTimeStatus
=
runTimeStatus
;
}
}
public
Integer
getWriteSelfCheckStatus
()
{
return
writeSelfCheckStatus
;
}
public
void
setWriteSelfCheckStatus
(
Integer
writeSelfCheckStatus
)
{
this
.
writeSelfCheckStatus
=
writeSelfCheckStatus
;
}
public
Integer
getRelayStatus
()
{
return
relayStatus
;
}
public
void
setRelayStatus
(
Integer
relayStatus
)
{
this
.
relayStatus
=
relayStatus
;
}
public
Integer
getPulseStatus
()
{
return
pulseStatus
;
}
public
void
setPulseStatus
(
Integer
pulseStatus
)
{
this
.
pulseStatus
=
pulseStatus
;
}
public
Integer
getModuleStatus
()
{
return
moduleStatus
;
}
public
void
setModuleStatus
(
Integer
moduleStatus
)
{
this
.
moduleStatus
=
moduleStatus
;
}
public
Integer
getSimCardStatus
()
{
return
simCardStatus
;
}
public
void
setSimCardStatus
(
Integer
simCardStatus
)
{
this
.
simCardStatus
=
simCardStatus
;
}
public
Integer
getNetworkStatus
()
{
return
networkStatus
;
}
public
void
setNetworkStatus
(
Integer
networkStatus
)
{
this
.
networkStatus
=
networkStatus
;
}
}
}
zhmes-agecal-system/src/main/java/com/zehong/system/domain/PalletDeviceBinding.java
View file @
79410fee
...
@@ -146,6 +146,37 @@ public class PalletDeviceBinding extends BaseEntity
...
@@ -146,6 +146,37 @@ public class PalletDeviceBinding extends BaseEntity
* 0-预热;1-正常;3-传感器故障;4-报警;5-通讯故障; 只有是4的时候显示正常,其他的都是异常
* 0-预热;1-正常;3-传感器故障;4-报警;5-通讯故障; 只有是4的时候显示正常,其他的都是异常
*/
*/
private
String
calibrationConcentrationStatus
;
private
String
calibrationConcentrationStatus
;
/**
* 写自检状态 空 是没写 0-失败;1-成功
*/
private
Integer
writeSelfCheckStatus
;
/**
* 继电器状态 0:初始 1:动作
*/
private
Integer
relayStatus
;
/**
* 脉冲状态 0:初始 1:动作
*/
private
Integer
pulseStatus
;
/**
* 模块状态 0:异常 1:正常
*/
private
Integer
moduleStatus
;
/**
* SIM卡状态 0:异常 1:正常
*/
private
Integer
simCardStatus
;
/**
* 网络状态 0:异常 1:正常
*/
private
Integer
networkStatus
;
public
String
getStatus
()
{
public
String
getStatus
()
{
return
status
;
return
status
;
}
}
...
@@ -370,17 +401,94 @@ public class PalletDeviceBinding extends BaseEntity
...
@@ -370,17 +401,94 @@ public class PalletDeviceBinding extends BaseEntity
this
.
calibrationConcentrationStatus
=
calibrationConcentrationStatus
;
this
.
calibrationConcentrationStatus
=
calibrationConcentrationStatus
;
}
}
public
Integer
getWriteSelfCheckStatus
()
{
return
writeSelfCheckStatus
;
}
public
void
setWriteSelfCheckStatus
(
Integer
writeSelfCheckStatus
)
{
this
.
writeSelfCheckStatus
=
writeSelfCheckStatus
;
}
public
Integer
getRelayStatus
()
{
return
relayStatus
;
}
public
void
setRelayStatus
(
Integer
relayStatus
)
{
this
.
relayStatus
=
relayStatus
;
}
public
Integer
getPulseStatus
()
{
return
pulseStatus
;
}
public
void
setPulseStatus
(
Integer
pulseStatus
)
{
this
.
pulseStatus
=
pulseStatus
;
}
public
Integer
getModuleStatus
()
{
return
moduleStatus
;
}
public
void
setModuleStatus
(
Integer
moduleStatus
)
{
this
.
moduleStatus
=
moduleStatus
;
}
public
Integer
getSimCardStatus
()
{
return
simCardStatus
;
}
public
void
setSimCardStatus
(
Integer
simCardStatus
)
{
this
.
simCardStatus
=
simCardStatus
;
}
public
Integer
getNetworkStatus
()
{
return
networkStatus
;
}
public
void
setNetworkStatus
(
Integer
networkStatus
)
{
this
.
networkStatus
=
networkStatus
;
}
@Override
@Override
public
String
toString
()
{
public
String
toString
()
{
return
new
ToStringBuilder
(
this
,
ToStringStyle
.
MULTI_LINE_STYLE
)
return
new
ToStringBuilder
(
this
,
ToStringStyle
.
MULTI_LINE_STYLE
)
.
append
(
"palletDeviceBindingId"
,
getPalletDeviceBindingId
())
.
append
(
"palletDeviceBindingId"
,
getPalletDeviceBindingId
())
.
append
(
"trayId"
,
getTrayId
())
.
append
(
"trayId"
,
getTrayId
())
.
append
(
"fTrayCode"
,
getfTrayCode
())
.
append
(
"deviceCode"
,
getDeviceCode
())
.
append
(
"deviceCode"
,
getDeviceCode
())
.
append
(
"row"
,
getRow
())
.
append
(
"row"
,
getRow
())
.
append
(
"col"
,
getCol
())
.
append
(
"col"
,
getCol
())
.
append
(
"index"
,
getIndex
())
.
append
(
"number"
,
getNumber
())
.
append
(
"bindingTime"
,
getBindingTime
())
.
append
(
"bindingTime"
,
getBindingTime
())
.
append
(
"unbindingTime"
,
getUnbindingTime
())
.
append
(
"unbindingTime"
,
getUnbindingTime
())
.
append
(
"status"
,
getStatus
())
.
append
(
"recordYear"
,
getRecordYear
())
.
append
(
"recordMonth"
,
getRecordMonth
())
.
append
(
"recordDate"
,
getRecordDate
())
.
append
(
"recordHour"
,
getRecordHour
())
.
append
(
"recordMinute"
,
getRecordMinute
())
.
append
(
"writeTimeStatus"
,
getWriteTimeStatus
())
.
append
(
"adjustmentZeroAd"
,
getAdjustmentZeroAd
())
.
append
(
"zeroStatus"
,
getZeroStatus
())
.
append
(
"calibrationAd"
,
getCalibrationAd
())
.
append
(
"calibrationAdStatus"
,
getCalibrationAdStatus
())
.
append
(
"concentration"
,
getConcentration
())
.
append
(
"runTimeStatus"
,
getRunTimeStatus
())
.
append
(
"realTimeAd"
,
getRealTimeAd
())
.
append
(
"realTimeStatus"
,
getRealTimeStatus
())
.
append
(
"calibrationConcentration"
,
getCalibrationConcentration
())
.
append
(
"calibrationConcentrationStatus"
,
getCalibrationConcentrationStatus
())
.
append
(
"writeSelfCheckStatus"
,
getWriteSelfCheckStatus
())
.
append
(
"relayStatus"
,
getRelayStatus
())
.
append
(
"pulseStatus"
,
getPulseStatus
())
.
append
(
"moduleStatus"
,
getModuleStatus
())
.
append
(
"simCardStatus"
,
getSimCardStatus
())
.
append
(
"networkStatus"
,
getNetworkStatus
())
.
append
(
"createTime"
,
getCreateTime
())
.
append
(
"createTime"
,
getCreateTime
())
.
append
(
"updateTime"
,
getUpdateTime
())
.
append
(
"createBy"
,
getCreateBy
())
.
append
(
"updateBy"
,
getUpdateBy
())
.
toString
();
.
toString
();
}
}
}
}
zhmes-agecal-system/src/main/java/com/zehong/system/domain/PalletDeviceUploadHistory.java
View file @
79410fee
...
@@ -128,6 +128,36 @@ public class PalletDeviceUploadHistory extends BaseEntity
...
@@ -128,6 +128,36 @@ public class PalletDeviceUploadHistory extends BaseEntity
* 0-预热;1-正常;3-传感器故障;4-报警;5-通讯故障; 只有是4的时候显示正常,其他的都是异常
* 0-预热;1-正常;3-传感器故障;4-报警;5-通讯故障; 只有是4的时候显示正常,其他的都是异常
*/
*/
private
String
calibrationConcentrationStatus
;
private
String
calibrationConcentrationStatus
;
/**
* 写自检状态 空 是没写 0-失败;1-成功
*/
private
Integer
writeSelfCheckStatus
;
/**
* 继电器状态 0:初始 1:动作
*/
private
Integer
relayStatus
;
/**
* 脉冲状态 0:初始 1:动作
*/
private
Integer
pulseStatus
;
/**
* 模块状态 0:异常 1:正常
*/
private
Integer
moduleStatus
;
/**
* SIM卡状态 0:异常 1:正常
*/
private
Integer
simCardStatus
;
/**
* 网络状态 0:异常 1:正常
*/
private
Integer
networkStatus
;
public
void
setId
(
Long
id
)
public
void
setId
(
Long
id
)
{
{
this
.
id
=
id
;
this
.
id
=
id
;
...
@@ -369,34 +399,90 @@ public class PalletDeviceUploadHistory extends BaseEntity
...
@@ -369,34 +399,90 @@ public class PalletDeviceUploadHistory extends BaseEntity
this
.
calibrationConcentrationStatus
=
calibrationConcentrationStatus
;
this
.
calibrationConcentrationStatus
=
calibrationConcentrationStatus
;
}
}
public
Integer
getWriteSelfCheckStatus
()
{
return
writeSelfCheckStatus
;
}
public
void
setWriteSelfCheckStatus
(
Integer
writeSelfCheckStatus
)
{
this
.
writeSelfCheckStatus
=
writeSelfCheckStatus
;
}
public
Integer
getRelayStatus
()
{
return
relayStatus
;
}
public
void
setRelayStatus
(
Integer
relayStatus
)
{
this
.
relayStatus
=
relayStatus
;
}
public
Integer
getPulseStatus
()
{
return
pulseStatus
;
}
public
void
setPulseStatus
(
Integer
pulseStatus
)
{
this
.
pulseStatus
=
pulseStatus
;
}
public
Integer
getModuleStatus
()
{
return
moduleStatus
;
}
public
void
setModuleStatus
(
Integer
moduleStatus
)
{
this
.
moduleStatus
=
moduleStatus
;
}
public
Integer
getSimCardStatus
()
{
return
simCardStatus
;
}
public
void
setSimCardStatus
(
Integer
simCardStatus
)
{
this
.
simCardStatus
=
simCardStatus
;
}
public
Integer
getNetworkStatus
()
{
return
networkStatus
;
}
public
void
setNetworkStatus
(
Integer
networkStatus
)
{
this
.
networkStatus
=
networkStatus
;
}
@Override
@Override
public
String
toString
()
{
public
String
toString
()
{
return
new
ToStringBuilder
(
this
,
ToStringStyle
.
MULTI_LINE_STYLE
)
return
"PalletDeviceUploadHistory{"
+
.
append
(
"id"
,
getId
())
"id="
+
id
+
.
append
(
"trayId"
,
getTrayId
())
", trayId="
+
trayId
+
.
append
(
"deviceCode"
,
getDeviceCode
())
", trayCode='"
+
trayCode
+
'\''
+
.
append
(
"row"
,
getRow
())
", deviceCode='"
+
deviceCode
+
'\''
+
.
append
(
"col"
,
getCol
())
", row="
+
row
+
.
append
(
"index"
,
getIndex
())
", col="
+
col
+
.
append
(
"number"
,
getNumber
())
", index="
+
index
+
.
append
(
"bindingTime"
,
getBindingTime
())
", number="
+
number
+
.
append
(
"unbindingTime"
,
getUnbindingTime
())
", bindingTime="
+
bindingTime
+
.
append
(
"createTime"
,
getCreateTime
())
", unbindingTime="
+
unbindingTime
+
.
append
(
"status"
,
getStatus
())
", status='"
+
status
+
'\''
+
.
append
(
"recordYear"
,
getRecordYear
())
", recordYear='"
+
recordYear
+
'\''
+
.
append
(
"recordMonth"
,
getRecordMonth
())
", recordMonth='"
+
recordMonth
+
'\''
+
.
append
(
"recordDate"
,
getRecordDate
())
", recordDate='"
+
recordDate
+
'\''
+
.
append
(
"recordHour"
,
getRecordHour
())
", recordHour='"
+
recordHour
+
'\''
+
.
append
(
"recordMinute"
,
getRecordMinute
())
", recordMinute='"
+
recordMinute
+
'\''
+
.
append
(
"writeTimeStatus"
,
getWriteTimeStatus
())
", writeTimeStatus='"
+
writeTimeStatus
+
'\''
+
.
append
(
"adjustmentZeroAd"
,
getAdjustmentZeroAd
())
", adjustmentZeroAd='"
+
adjustmentZeroAd
+
'\''
+
.
append
(
"zeroStatus"
,
getZeroStatus
())
", zeroStatus='"
+
zeroStatus
+
'\''
+
.
append
(
"calibrationAd"
,
getCalibrationAd
())
", calibrationAd='"
+
calibrationAd
+
'\''
+
.
append
(
"calibrationStatus"
,
getCalibrationStatus
())
", calibrationStatus='"
+
calibrationStatus
+
'\''
+
.
append
(
"concentration"
,
getConcentration
())
", concentration='"
+
concentration
+
'\''
+
.
append
(
"runTimeStatus"
,
getRunTimeStatus
())
", runTimeStatus='"
+
runTimeStatus
+
'\''
+
.
append
(
"realTimeAd"
,
getRealTimeAd
())
", realTimeAd="
+
realTimeAd
+
.
append
(
"realTimeAdStatus"
,
getRealTimeAdStatus
())
", realTimeAdStatus='"
+
realTimeAdStatus
+
'\''
+
.
toString
();
", calibrationConcentration="
+
calibrationConcentration
+
", calibrationConcentrationStatus='"
+
calibrationConcentrationStatus
+
'\''
+
", writeSelfCheckStatus="
+
writeSelfCheckStatus
+
", relayStatus="
+
relayStatus
+
", pulseStatus="
+
pulseStatus
+
", moduleStatus="
+
moduleStatus
+
", simCardStatus="
+
simCardStatus
+
", networkStatus="
+
networkStatus
+
'}'
;
}
}
}
}
zhmes-agecal-system/src/main/java/com/zehong/system/mapper/PalletDeviceBindingMapper.java
View file @
79410fee
...
@@ -54,8 +54,6 @@ public interface PalletDeviceBindingMapper
...
@@ -54,8 +54,6 @@ public interface PalletDeviceBindingMapper
*/
*/
public
int
insertPalletDeviceBinding
(
PalletDeviceBinding
palletDeviceBinding
);
public
int
insertPalletDeviceBinding
(
PalletDeviceBinding
palletDeviceBinding
);
public
int
resetAll
(
Long
trayId
);
public
int
deleteAllByTrayId
(
Long
trayId
);
public
int
deleteAllByTrayId
(
Long
trayId
);
public
int
batchInsertPalletDeviceBinding
(
@Param
(
"palletDeviceBindingList"
)
List
<
PalletDeviceBinding
>
palletDeviceBindingList
);
public
int
batchInsertPalletDeviceBinding
(
@Param
(
"palletDeviceBindingList"
)
List
<
PalletDeviceBinding
>
palletDeviceBindingList
);
...
@@ -72,6 +70,8 @@ public interface PalletDeviceBindingMapper
...
@@ -72,6 +70,8 @@ public interface PalletDeviceBindingMapper
public
int
unbindDevice
(
Long
palletDeviceBindingId
);
public
int
unbindDevice
(
Long
palletDeviceBindingId
);
public
int
resetAll
(
Long
trayId
);
public
int
batchUpdateDeviceCode
(
@Param
(
"palletDeviceBindingList"
)
List
<
PalletDeviceBinding
>
palletDeviceBindingList
);
public
int
batchUpdateDeviceCode
(
@Param
(
"palletDeviceBindingList"
)
List
<
PalletDeviceBinding
>
palletDeviceBindingList
);
public
int
batchUpdateAdAndStatus
(
@Param
(
"palletDeviceBindingList"
)
List
<
PalletDeviceBinding
>
palletDeviceBindingList
);
public
int
batchUpdateAdAndStatus
(
@Param
(
"palletDeviceBindingList"
)
List
<
PalletDeviceBinding
>
palletDeviceBindingList
);
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/modbus/util/Modbus4jUtils.java
View file @
79410fee
...
@@ -9,9 +9,10 @@ import com.serotonin.modbus4j.exception.ErrorResponseException;
...
@@ -9,9 +9,10 @@ import com.serotonin.modbus4j.exception.ErrorResponseException;
import
com.serotonin.modbus4j.exception.ModbusInitException
;
import
com.serotonin.modbus4j.exception.ModbusInitException
;
import
com.serotonin.modbus4j.exception.ModbusTransportException
;
import
com.serotonin.modbus4j.exception.ModbusTransportException
;
import
com.serotonin.modbus4j.ip.IpParameters
;
import
com.serotonin.modbus4j.ip.IpParameters
;
import
com.serotonin.modbus4j.ip.tcp.TcpMaster
;
import
com.serotonin.modbus4j.locator.BaseLocator
;
import
com.serotonin.modbus4j.locator.BaseLocator
;
import
com.serotonin.modbus4j.msg.*
;
import
com.serotonin.modbus4j.msg.*
;
import
com.zehong.system.
domain.PalletDeviceBinding
;
import
com.zehong.system.
modbus.handler.ModbusResultHandler
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
...
@@ -35,6 +36,9 @@ public class Modbus4jUtils {
...
@@ -35,6 +36,9 @@ public class Modbus4jUtils {
private
static
final
int
MAX_RETRIES
=
3
;
// 最大重试次数
private
static
final
int
MAX_RETRIES
=
3
;
// 最大重试次数
private
static
final
int
RETRY_DELAY
=
500
;
// 重试延迟(ms)// 监控参数
private
static
final
int
RETRY_DELAY
=
500
;
// 重试延迟(ms)// 监控参数
private
static
final
int
MONITOR_INTERVAL
=
5000
;
// 监控间隔(ms)
private
static
final
int
MONITOR_INTERVAL
=
5000
;
// 监控间隔(ms)
// Modbus配置:取消内置重试,统一用自定义重试
private
static
final
int
MODBUS_CONN_TIMEOUT_MS
=
3000
;
// 连接超时:3秒
private
static
final
int
CUSTOM_RETRY_TIMES
=
2
;
// 自定义重试次数:1次
// 监控控制标志
// 监控控制标志
private
static
final
AtomicBoolean
monitoring
=
new
AtomicBoolean
(
false
);
private
static
final
AtomicBoolean
monitoring
=
new
AtomicBoolean
(
false
);
...
@@ -48,7 +52,6 @@ public class Modbus4jUtils {
...
@@ -48,7 +52,6 @@ public class Modbus4jUtils {
modbusFactory
=
new
ModbusFactory
();
modbusFactory
=
new
ModbusFactory
();
}
}
}
}
/**
/**
* 获取master
* 获取master
*
*
...
@@ -73,24 +76,34 @@ public class Modbus4jUtils {
...
@@ -73,24 +76,34 @@ public class Modbus4jUtils {
return
master
;
return
master
;
}
}
// -------------------------- Modbus工具方法(显式抛出异常)--------------------------
/**
/**
* 动态获取 modubus master
* 创建Modbus连接(取消内置重试,统一自定义重试)
* @param ip ip
* @param port port
* @return r
* @throws ModbusInitException m
*/
*/
public
static
ModbusMaster
get
Master
(
String
ip
,
int
port
)
throws
ModbusInitException
{
public
static
ModbusMaster
createModbus
Master
(
String
ip
,
int
port
)
throws
ModbusInitException
{
IpParameters
params
=
new
IpParameters
();
IpParameters
params
=
new
IpParameters
();
params
.
setHost
(
ip
);
params
.
setHost
(
ip
);
params
.
setPort
(
port
);
params
.
setPort
(
port
);
ModbusMaster
master
=
modbusFactory
.
createTcpMaster
(
params
,
false
);
// TCP 协议
master
.
setTimeout
(
3000
);
// 设置超时时间
TcpMaster
master
=
(
TcpMaster
)
modbusFactory
.
createTcpMaster
(
params
,
true
);
master
.
setRetries
(
3
);
// 设置重试次数
master
.
setTimeout
(
MODBUS_CONN_TIMEOUT_MS
);
master
.
setRetries
(
0
);
master
.
init
();
master
.
init
();
return
master
;
return
master
;
}
}
/**
* 销毁Modbus连接(反射失败直接抛出异常,显式暴露问题)
*/
public
static
void
destroyModbusMaster
(
ModbusMaster
master
,
int
deviceId
)
{
if
(
master
!=
null
)
{
try
{
master
.
destroy
();
}
catch
(
Exception
e
)
{
log
.
debug
(
"设备{}: ModbusMaster销毁异常"
,
deviceId
,
e
);
}
}
}
/**
/**
* 读取[01 Coil Status 0x]类型 开关数据
* 读取[01 Coil Status 0x]类型 开关数据
*
*
...
@@ -180,7 +193,7 @@ public class Modbus4jUtils {
...
@@ -180,7 +193,7 @@ public class Modbus4jUtils {
ModbusMaster
master
=
null
;
ModbusMaster
master
=
null
;
try
{
try
{
master
=
get
Master
(
"192.168.1.11"
,
503
);
master
=
createModbus
Master
(
"192.168.1.11"
,
503
);
boolean
[]
booleans
=
readDiscreteInputs
(
master
,
1
,
0
,
2
);
boolean
[]
booleans
=
readDiscreteInputs
(
master
,
1
,
0
,
2
);
if
(
master
!=
null
)
{
if
(
master
!=
null
)
{
...
@@ -208,7 +221,7 @@ public class Modbus4jUtils {
...
@@ -208,7 +221,7 @@ public class Modbus4jUtils {
public
static
boolean
[]
getRoboticArmExitConveyorData
(
String
ip
,
int
port
)
{
public
static
boolean
[]
getRoboticArmExitConveyorData
(
String
ip
,
int
port
)
{
ModbusMaster
master
=
null
;
ModbusMaster
master
=
null
;
try
{
try
{
master
=
get
Master
(
ip
,
port
);
master
=
createModbus
Master
(
ip
,
port
);
boolean
[]
booleans
=
readDiscreteInputs
(
master
,
1
,
0
,
2
);
boolean
[]
booleans
=
readDiscreteInputs
(
master
,
1
,
0
,
2
);
if
(
master
!=
null
)
{
if
(
master
!=
null
)
{
...
@@ -778,7 +791,7 @@ public class Modbus4jUtils {
...
@@ -778,7 +791,7 @@ public class Modbus4jUtils {
ModbusMaster
modbusMaster
=
null
;
ModbusMaster
modbusMaster
=
null
;
try
{
try
{
// 读取 第1个 pcba 板子的数据
// 读取 第1个 pcba 板子的数据
modbusMaster
=
get
Master
(
"192.168.2.1"
,
501
);
modbusMaster
=
createModbus
Master
(
"192.168.2.1"
,
501
);
writeCurrentTimeToDevice
(
modbusMaster
,
1
);
writeCurrentTimeToDevice
(
modbusMaster
,
1
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
e
.
printStackTrace
();
...
@@ -820,6 +833,64 @@ public class Modbus4jUtils {
...
@@ -820,6 +833,64 @@ public class Modbus4jUtils {
}
}
}
}
/**
* 带重试的设备读取
*/
public
static
int
[]
readDeviceWithRetry
(
String
ip
,
int
port
,
int
deviceId
)
{
ModbusMaster
master
=
null
;
int
[]
lastResult
=
null
;
// 用于记录最后一次读取的结果(无论是否满足停止条件)
try
{
// 只创建一次ModbusMaster,循环内复用
master
=
Modbus4jUtils
.
createModbusMaster
(
ip
,
port
);
for
(
int
retry
=
0
;
retry
<=
CUSTOM_RETRY_TIMES
;
retry
++)
{
try
{
// 执行读取操作,获取本次结果
int
[]
currentResult
=
readDeviceRegisters
(
master
,
deviceId
);
// 更新最后一次结果(无论是否满足停止条件,都记录)
lastResult
=
currentResult
;
// 检查停止条件,如果满足则提前返回(无需等到重试耗尽)
if
(
ModbusResultHandler
.
createDefaultStopCondition
().
test
(
currentResult
))
{
log
.
info
(
"设备{}第{}次读取成功(满足条件): ip={}, port={}"
,
deviceId
,
retry
+
1
,
ip
,
port
);
return
currentResult
;
}
// 未满足条件且不是最后一次重试,休眠后继续
if
(
retry
<
CUSTOM_RETRY_TIMES
)
{
log
.
info
(
"设备{}第{}次读取未满足条件,准备重试: ip={}, port={}"
,
deviceId
,
retry
+
1
,
ip
,
port
);
Thread
.
sleep
(
200
);
}
}
catch
(
Exception
e
)
{
// 本次读取发生异常,记录日志但不中断重试(继续下一次)
log
.
warn
(
"设备{}第{}次读取发生异常: ip={}, port={}"
,
deviceId
,
retry
+
1
,
ip
,
port
,
e
);
// 如果是最后一次重试,异常时lastResult可能为null(需后续处理)
}
}
// 循环结束(重试耗尽),此时lastResult为最后一次的结果(可能是正常读取但不满足条件,或null)
log
.
info
(
"设备{}重试次数耗尽,返回最后一次结果: ip={}, port={}"
,
deviceId
,
ip
,
port
);
}
catch
(
Exception
e
)
{
// 捕获创建ModbusMaster或休眠时的异常(非读取操作的异常)
log
.
error
(
"设备{}连接创建或休眠失败: ip={}, port={}"
,
deviceId
,
ip
,
port
,
e
);
throw
new
RuntimeException
(
"设备连接或操作异常"
,
e
);
}
finally
{
// 无论结果如何,最终销毁连接
destroyModbusMaster
(
master
,
deviceId
);
}
// 处理最后一次结果可能为null的情况(例如所有重试都异常)
if
(
lastResult
==
null
)
{
throw
new
RuntimeException
(
"设备所有读取尝试均失败(无有效结果)"
);
}
return
lastResult
;
}
/**
/**
* 读取设备寄存器(线程安全版)
* 读取设备寄存器(线程安全版)
*/
*/
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/netty/event/CalibrationResultEventHandler.java
View file @
79410fee
...
@@ -117,6 +117,13 @@ public class CalibrationResultEventHandler {
...
@@ -117,6 +117,13 @@ public class CalibrationResultEventHandler {
mesDeviceDomain
.
setRecordDate
(
palletDeviceBinding
.
getRecordDate
());
mesDeviceDomain
.
setRecordDate
(
palletDeviceBinding
.
getRecordDate
());
mesDeviceDomain
.
setRecordHour
(
palletDeviceBinding
.
getRecordHour
());
mesDeviceDomain
.
setRecordHour
(
palletDeviceBinding
.
getRecordHour
());
mesDeviceDomain
.
setRecordMinute
(
palletDeviceBinding
.
getRecordMinute
());
mesDeviceDomain
.
setRecordMinute
(
palletDeviceBinding
.
getRecordMinute
());
// 写入自检状态 继电器状态 脉冲状态 模块状态 SIM状态 网络状态
mesDeviceDomain
.
setWriteSelfCheckStatus
(
palletDeviceBinding
.
getWriteSelfCheckStatus
());
mesDeviceDomain
.
setRelayStatus
(
palletDeviceBinding
.
getRelayStatus
());
mesDeviceDomain
.
setPulseStatus
(
palletDeviceBinding
.
getPulseStatus
());
mesDeviceDomain
.
setModuleStatus
(
palletDeviceBinding
.
getModuleStatus
());
mesDeviceDomain
.
setSimCardStatus
(
palletDeviceBinding
.
getSimCardStatus
());
mesDeviceDomain
.
setNetworkStatus
(
palletDeviceBinding
.
getNetworkStatus
());
mesDeviceDomains
.
add
(
mesDeviceDomain
);
mesDeviceDomains
.
add
(
mesDeviceDomain
);
}
}
...
@@ -437,6 +444,14 @@ public class CalibrationResultEventHandler {
...
@@ -437,6 +444,14 @@ public class CalibrationResultEventHandler {
history
.
setCalibrationConcentration
(
binding
.
getCalibrationConcentration
());
history
.
setCalibrationConcentration
(
binding
.
getCalibrationConcentration
());
history
.
setCalibrationConcentrationStatus
(
binding
.
getCalibrationConcentrationStatus
());
history
.
setCalibrationConcentrationStatus
(
binding
.
getCalibrationConcentrationStatus
());
// 写入自检状态 继电器状态 脉冲状态 模组状态 SIM卡状态 网络状态
history
.
setWriteSelfCheckStatus
(
binding
.
getWriteSelfCheckStatus
());
history
.
setRelayStatus
(
binding
.
getRelayStatus
());
history
.
setPulseStatus
(
binding
.
getPulseStatus
());
history
.
setModuleStatus
(
binding
.
getModuleStatus
());
history
.
setSimCardStatus
(
binding
.
getSimCardStatus
());
history
.
setNetworkStatus
(
binding
.
getNetworkStatus
());
return
history
;
return
history
;
}
}
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/task/DeviceCommunicationJob.java
View file @
79410fee
package
com
.
zehong
.
system
.
task
;
package
com
.
zehong
.
system
.
task
;
import
com.serotonin.modbus4j.ModbusFactory
;
import
com.serotonin.modbus4j.ModbusMaster
;
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.PalletDeviceBinding
;
import
com.zehong.system.domain.TEquipmentAlarmData
;
import
com.zehong.system.domain.TEquipmentAlarmData
;
import
com.zehong.system.domain.TStoreyInfo
;
import
com.zehong.system.domain.TStoreyInfo
;
import
com.zehong.system.mapper.PalletDeviceBindingMapper
;
import
com.zehong.system.mapper.PalletDeviceBindingMapper
;
import
com.zehong.system.mapper.TStoreyInfoMapper
;
import
com.zehong.system.mapper.TStoreyInfoMapper
;
import
com.zehong.system.modbus.handler.ModbusResultHandler
;
import
com.zehong.system.modbus.util.Modbus4jUtils
;
import
com.zehong.system.modbus.util.Modbus4jUtils
;
import
com.zehong.system.service.ITEquipmentAlarmDataService
;
import
com.zehong.system.service.ITEquipmentAlarmDataService
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
...
@@ -47,12 +38,7 @@ public class DeviceCommunicationJob implements Job {
...
@@ -47,12 +38,7 @@ public class DeviceCommunicationJob implements Job {
// 超时控制:必须小于Cron周期(假设Cron为5分钟,这里留1分钟缓冲)
// 超时控制:必须小于Cron周期(假设Cron为5分钟,这里留1分钟缓冲)
private
static
final
int
TOTAL_TASK_TIMEOUT_SEC
=
240
;
// 任务总超时:4分钟
private
static
final
int
TOTAL_TASK_TIMEOUT_SEC
=
240
;
// 任务总超时:4分钟
private
static
final
int
SINGLE_DEVICE_TIMEOUT_SEC
=
10
;
// 单个设备超时:10秒
private
static
final
int
SINGLE_DEVICE_TIMEOUT_SEC
=
10
;
// 单个设备超时:10秒
// Modbus配置:取消内置重试,统一用自定义重试
private
static
final
int
MODBUS_CONN_TIMEOUT_MS
=
3000
;
// 连接超时:3秒
private
static
final
int
CUSTOM_RETRY_TIMES
=
2
;
// 自定义重试次数:1次
private
static
final
int
CUSTOM_RETRY_TIMES
=
2
;
// 自定义重试次数:1次
// Modbus寄存器配置
private
static
final
int
REG_START_ADDR
=
0
;
private
static
final
int
REG_READ_COUNT
=
10
;
// 全局线程池 - 避免重复创建
// 全局线程池 - 避免重复创建
private
static
final
ExecutorService
GLOBAL_DEVICE_EXECUTOR
=
new
ThreadPoolExecutor
(
private
static
final
ExecutorService
GLOBAL_DEVICE_EXECUTOR
=
new
ThreadPoolExecutor
(
...
@@ -61,9 +47,6 @@ public class DeviceCommunicationJob implements Job {
...
@@ -61,9 +47,6 @@ public class DeviceCommunicationJob implements Job {
r
->
new
Thread
(
r
,
"global-modbus-device"
),
r
->
new
Thread
(
r
,
"global-modbus-device"
),
new
ThreadPoolExecutor
.
CallerRunsPolicy
()
new
ThreadPoolExecutor
.
CallerRunsPolicy
()
);
);
// 工厂(单例)
private
static
final
ModbusFactory
modbusFactory
=
new
ModbusFactory
();
// -------------------------- 依赖注入 --------------------------
// -------------------------- 依赖注入 --------------------------
@Resource
@Resource
private
ITEquipmentAlarmDataService
alarmDataService
;
private
ITEquipmentAlarmDataService
alarmDataService
;
...
@@ -95,7 +78,7 @@ public class DeviceCommunicationJob implements Job {
...
@@ -95,7 +78,7 @@ public class DeviceCommunicationJob implements Job {
allPorts
.
get
(
TOTAL_TASK_TIMEOUT_SEC
,
TimeUnit
.
SECONDS
);
allPorts
.
get
(
TOTAL_TASK_TIMEOUT_SEC
,
TimeUnit
.
SECONDS
);
log
.
info
(
"任务执行成功: fStoreyId={}, 耗时={}ms"
,
log
.
info
(
"
DeviceCommunicationJob
任务执行成功: fStoreyId={}, 耗时={}ms"
,
storeyIdStr
,
System
.
currentTimeMillis
()
-
startTime
);
storeyIdStr
,
System
.
currentTimeMillis
()
-
startTime
);
}
catch
(
TimeoutException
e
)
{
}
catch
(
TimeoutException
e
)
{
...
@@ -158,7 +141,7 @@ public class DeviceCommunicationJob implements Job {
...
@@ -158,7 +141,7 @@ public class DeviceCommunicationJob implements Job {
PalletDeviceBinding
binding
=
null
;
PalletDeviceBinding
binding
=
null
;
try
{
try
{
// 1. 读取设备数据
// 1. 读取设备数据
int
[]
result
=
readDeviceWithRetry
(
ip
,
port
,
deviceId
);
int
[]
result
=
Modbus4jUtils
.
readDeviceWithRetry
(
ip
,
port
,
deviceId
);
// 2. 查询设备绑定信息
// 2. 查询设备绑定信息
binding
=
palletDeviceBindingMapper
.
selectByTrayIdAndIndex
(
ip
,
deviceId
);
binding
=
palletDeviceBindingMapper
.
selectByTrayIdAndIndex
(
ip
,
deviceId
);
...
@@ -178,7 +161,7 @@ public class DeviceCommunicationJob implements Job {
...
@@ -178,7 +161,7 @@ public class DeviceCommunicationJob implements Job {
// 4. 条件写入时间
// 4. 条件写入时间
if
(
result
[
1
]
==
1
||
result
[
1
]
==
3
||
result
[
1
]
==
4
)
{
if
(
result
[
1
]
==
1
||
result
[
1
]
==
3
||
result
[
1
]
==
4
)
{
// 重用之前的master连接进行写操作
// 重用之前的master连接进行写操作
master
=
createModbusMaster
(
ip
,
port
);
master
=
Modbus4jUtils
.
createModbusMaster
(
ip
,
port
);
writeCurrentTimeToDevice
(
master
,
deviceId
,
binding
);
writeCurrentTimeToDevice
(
master
,
deviceId
,
binding
);
}
}
...
@@ -201,7 +184,7 @@ public class DeviceCommunicationJob implements Job {
...
@@ -201,7 +184,7 @@ public class DeviceCommunicationJob implements Job {
errorCount
.
incrementAndGet
();
errorCount
.
incrementAndGet
();
return
false
;
return
false
;
}
finally
{
}
finally
{
destroyModbusMaster
(
master
,
deviceId
);
Modbus4jUtils
.
destroyModbusMaster
(
master
,
deviceId
);
}
}
},
GLOBAL_DEVICE_EXECUTOR
);
},
GLOBAL_DEVICE_EXECUTOR
);
}
}
...
@@ -232,64 +215,6 @@ public class DeviceCommunicationJob implements Job {
...
@@ -232,64 +215,6 @@ public class DeviceCommunicationJob implements Job {
}
}
}
}
/**
* 带重试的设备读取
*/
private
int
[]
readDeviceWithRetry
(
String
ip
,
int
port
,
int
deviceId
)
{
ModbusMaster
master
=
null
;
int
[]
lastResult
=
null
;
// 用于记录最后一次读取的结果(无论是否满足停止条件)
try
{
// 只创建一次ModbusMaster,循环内复用
master
=
createModbusMaster
(
ip
,
port
);
for
(
int
retry
=
0
;
retry
<=
CUSTOM_RETRY_TIMES
;
retry
++)
{
try
{
// 执行读取操作,获取本次结果
int
[]
currentResult
=
readDeviceRegisters
(
master
,
deviceId
);
// 更新最后一次结果(无论是否满足停止条件,都记录)
lastResult
=
currentResult
;
// 检查停止条件,如果满足则提前返回(无需等到重试耗尽)
if
(
ModbusResultHandler
.
createDefaultStopCondition
().
test
(
currentResult
))
{
log
.
info
(
"设备{}第{}次读取成功(满足条件): ip={}, port={}"
,
deviceId
,
retry
+
1
,
ip
,
port
);
return
currentResult
;
}
// 未满足条件且不是最后一次重试,休眠后继续
if
(
retry
<
CUSTOM_RETRY_TIMES
)
{
log
.
info
(
"设备{}第{}次读取未满足条件,准备重试: ip={}, port={}"
,
deviceId
,
retry
+
1
,
ip
,
port
);
Thread
.
sleep
(
200
);
}
}
catch
(
Exception
e
)
{
// 本次读取发生异常,记录日志但不中断重试(继续下一次)
log
.
warn
(
"设备{}第{}次读取发生异常: ip={}, port={}"
,
deviceId
,
retry
+
1
,
ip
,
port
,
e
);
// 如果是最后一次重试,异常时lastResult可能为null(需后续处理)
}
}
// 循环结束(重试耗尽),此时lastResult为最后一次的结果(可能是正常读取但不满足条件,或null)
log
.
info
(
"设备{}重试次数耗尽,返回最后一次结果: ip={}, port={}"
,
deviceId
,
ip
,
port
);
}
catch
(
Exception
e
)
{
// 捕获创建ModbusMaster或休眠时的异常(非读取操作的异常)
log
.
error
(
"设备{}连接创建或休眠失败: ip={}, port={}"
,
deviceId
,
ip
,
port
,
e
);
throw
new
RuntimeException
(
"设备连接或操作异常"
,
e
);
}
finally
{
// 无论结果如何,最终销毁连接
destroyModbusMaster
(
master
,
deviceId
);
}
// 处理最后一次结果可能为null的情况(例如所有重试都异常)
if
(
lastResult
==
null
)
{
throw
new
RuntimeException
(
"设备所有读取尝试均失败(无有效结果)"
);
}
return
lastResult
;
}
/**
/**
* 写入当前时间到设备
* 写入当前时间到设备
*/
*/
...
@@ -327,58 +252,15 @@ public class DeviceCommunicationJob implements Job {
...
@@ -327,58 +252,15 @@ public class DeviceCommunicationJob implements Job {
log
.
error
(
"设备{}时间写入异常"
,
deviceId
,
e
);
log
.
error
(
"设备{}时间写入异常"
,
deviceId
,
e
);
recordAlarmByBinding
(
binding
,
"设备时间写入异常: "
+
e
.
getMessage
());
recordAlarmByBinding
(
binding
,
"设备时间写入异常: "
+
e
.
getMessage
());
}
}
}
// -------------------------- Modbus工具方法(显式抛出异常)--------------------------
/**
* 创建Modbus连接(取消内置重试,统一自定义重试)
*/
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
.
init
();
return
master
;
}
/**
// 20251206 写完时间写自检,写自检就在时间后边写就行,不管时间写不写成功
* 读取设备寄存器(异常直接抛出)
*/
private
int
[]
readDeviceRegisters
(
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
))
{
log
.
info
(
"无效Modbus响应类型:"
+
response
.
getClass
().
getName
()
+
",deviceId="
+
deviceId
);
}
assert
response
instanceof
ReadHoldingRegistersResponse
;
ReadHoldingRegistersResponse
regResp
=
(
ReadHoldingRegistersResponse
)
response
;
short
[]
signedVals
=
regResp
.
getShortData
();
int
[]
unsignedVals
=
new
int
[
signedVals
.
length
];
for
(
int
i
=
0
;
i
<
signedVals
.
length
;
i
++)
{
unsignedVals
[
i
]
=
signedVals
[
i
]
&
0xFFFF
;
// 转换为无符号整数
}
log
.
info
(
"设备寄存器读取结果:deviceId={},值={}"
,
deviceId
,
Arrays
.
toString
(
unsignedVals
));
return
unsignedVals
;
}
/**
* 销毁Modbus连接(反射失败直接抛出异常,显式暴露问题)
*/
private
void
destroyModbusMaster
(
ModbusMaster
master
,
int
deviceId
)
{
if
(
master
!=
null
)
{
try
{
try
{
master
.
destroy
();
Modbus4jUtils
.
writeRegister
(
master
,
deviceId
,
15
,
(
short
)
1
);
binding
.
setWriteSelfCheckStatus
(
1
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
log
.
debug
(
"设备{}: ModbusMaster销毁异常"
,
deviceId
,
e
);
binding
.
setWriteSelfCheckStatus
(
0
);
}
}
}
}
}
// -------------------------- 辅助方法(日志/告警)--------------------------
// -------------------------- 辅助方法(日志/告警)--------------------------
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/task/FinalExecutionJob.java
View file @
79410fee
package
com
.
zehong
.
system
.
task
;
package
com
.
zehong
.
system
.
task
;
import
com.serotonin.modbus4j.ModbusFactory
;
import
com.serotonin.modbus4j.ModbusMaster
;
import
com.serotonin.modbus4j.ModbusMaster
;
import
com.serotonin.modbus4j.exception.ModbusInitException
;
import
com.serotonin.modbus4j.exception.ModbusInitException
;
import
com.serotonin.modbus4j.exception.ModbusTransportException
;
import
com.serotonin.modbus4j.exception.ModbusTransportException
;
import
com.zehong.common.utils.StringUtils
;
import
com.zehong.common.utils.StringUtils
;
import
com.zehong.system.domain.
RobotArmCommand
;
import
com.zehong.system.domain.
PalletDeviceBinding
;
import
com.zehong.system.domain.TEquipmentAlarmData
;
import
com.zehong.system.domain.TEquipmentAlarmData
;
import
com.zehong.system.domain.TStoreyInfo
;
import
com.zehong.system.domain.TStoreyInfo
;
import
com.zehong.system.domain.TTrayInfo
;
import
com.zehong.system.domain.TTrayInfo
;
import
com.zehong.system.mapper.
RobotArmCommand
Mapper
;
import
com.zehong.system.mapper.
PalletDeviceBinding
Mapper
;
import
com.zehong.system.mapper.TStoreyInfoMapper
;
import
com.zehong.system.mapper.TStoreyInfoMapper
;
import
com.zehong.system.mapper.TTrayInfoMapper
;
import
com.zehong.system.mapper.TTrayInfoMapper
;
import
com.zehong.system.modbus.util.Modbus4jUtils
;
import
com.zehong.system.modbus.util.Modbus4jUtils
;
import
com.zehong.system.service.IRobotArmCommandService
;
import
com.zehong.system.service.IRobotArmCommandService
;
import
com.zehong.system.service.ITEquipmentAlarmDataService
;
import
com.zehong.system.service.ITEquipmentAlarmDataService
;
import
com.zehong.system.service.ITStoreyInfoService
;
import
com.zehong.system.service.websocket.RobotArmWebSocketHandler
;
import
com.zehong.system.service.websocket.RobotArmWebSocketHandler
;
import
org.quartz.*
;
import
org.quartz.*
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
...
@@ -22,17 +22,26 @@ import org.slf4j.LoggerFactory;
...
@@ -22,17 +22,26 @@ import org.slf4j.LoggerFactory;
import
org.springframework.stereotype.Component
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
import
javax.annotation.Resource
;
import
java.util.Arrays
;
import
java.util.Date
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.concurrent.*
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.stream.Collectors
;
/**
/**
* @author lenovo
* @author lenovo
* @date 2025/6/25
* @date 2025/6/25
* @description
TODO
* @description
老化最终执行任务
*/
*/
@Component
@Component
public
class
FinalExecutionJob
implements
Job
{
public
class
FinalExecutionJob
implements
Job
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
FinalExecutionJob
.
class
);
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
FinalExecutionJob
.
class
);
// -------------------------- 常量配置(统一管理,避免魔法值)--------------------------
// 超时控制:必须小于Cron周期(假设Cron为5分钟,这里留1分钟缓冲)
private
static
final
int
TOTAL_TASK_TIMEOUT_SEC
=
240
;
// 任务总超时:4分钟
private
static
final
int
SINGLE_DEVICE_TIMEOUT_SEC
=
10
;
// 单个设备超时:10秒
@Resource
@Resource
private
RobotArmWebSocketHandler
robotArmWebSocketHandler
;
private
RobotArmWebSocketHandler
robotArmWebSocketHandler
;
@Resource
@Resource
...
@@ -48,16 +57,27 @@ public class FinalExecutionJob implements Job {
...
@@ -48,16 +57,27 @@ public class FinalExecutionJob implements Job {
@Resource
@Resource
private
IRobotArmCommandService
robotArmCommandService
;
private
IRobotArmCommandService
robotArmCommandService
;
@Resource
private
PalletDeviceBindingMapper
palletDeviceBindingMapper
;
// 全局线程池 - 避免重复创建
private
static
final
ExecutorService
GLOBAL_DEVICE_EXECUTOR
=
new
ThreadPoolExecutor
(
50
,
100
,
60
,
TimeUnit
.
SECONDS
,
new
LinkedBlockingQueue
<>(
500
),
r
->
new
Thread
(
r
,
"final-global-modbus-device"
),
new
ThreadPoolExecutor
.
CallerRunsPolicy
()
);
// 工厂(单例)
private
static
final
ModbusFactory
modbusFactory
=
new
ModbusFactory
();
@Override
@Override
public
void
execute
(
JobExecutionContext
context
)
{
public
void
execute
(
JobExecutionContext
context
)
{
// 1. 初始化变量,避免空指针
// 1. 初始化变量,避免空指针
JobDataMap
data
;
JobDataMap
data
;
String
fPowerOutageIp
;
String
fPowerOutageIp
;
Long
fStoreyId
=
null
;
Long
fStoreyId
=
null
;
Integer
fPowerOutagePort
;
int
fPowerOutagePort
;
TStoreyInfo
tStoreyInfo
=
null
;
TStoreyInfo
tStoreyInfo
=
null
;
TTrayInfo
tTrayInfo
;
TTrayInfo
tTrayInfo
;
long
startTime
=
System
.
currentTimeMillis
();
try
{
try
{
// 2. 提取并校验所有参数
// 2. 提取并校验所有参数
...
@@ -109,6 +129,23 @@ public class FinalExecutionJob implements Job {
...
@@ -109,6 +129,23 @@ public class FinalExecutionJob implements Job {
// recordAlarm(tStoreyInfo, "Modbus写操作失败:" + e.getMessage());
// recordAlarm(tStoreyInfo, "Modbus写操作失败:" + e.getMessage());
// }
// }
// 20251206 读取 继电器状态 脉冲状态 模组状态 SIM卡状态 网络状态
// 并行处理3个端口
// List<CompletableFuture<Void>> portFutures = Arrays.asList(
// processPort(tStoreyInfo, 501, 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)),
// processPort(tStoreyInfo, 502, 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)),
// processPort(tStoreyInfo, 503, Arrays.asList(55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72))
// );
// // 等待所有端口完成,带总超时
// CompletableFuture<Void> allPorts = CompletableFuture.allOf(
// portFutures.toArray(new CompletableFuture[0])
// );
//
// allPorts.get(TOTAL_TASK_TIMEOUT_SEC, TimeUnit.SECONDS);
//
// log.info("FinalExecutionJob 任务执行成功: fStoreyId={}, 耗时={}ms",
// tStoreyInfo.getfStoreyId(), System.currentTimeMillis() - startTime);
// 6. 更新设备状态(DB操作单独捕获异常)
// 6. 更新设备状态(DB操作单独捕获异常)
try
{
try
{
tStoreyInfo
.
setfStatus
(
"4"
);
tStoreyInfo
.
setfStatus
(
"4"
);
...
@@ -161,7 +198,99 @@ public class FinalExecutionJob implements Job {
...
@@ -161,7 +198,99 @@ public class FinalExecutionJob implements Job {
log
.
error
(
"=== FinalExecutionJob finally:fStoreyId={} ==="
,
fStoreyId
);
log
.
error
(
"=== FinalExecutionJob finally:fStoreyId={} ==="
,
fStoreyId
);
}
}
}
}
/**
* 处理单个端口的所有设备
*/
private
CompletableFuture
<
Void
>
processPort
(
TStoreyInfo
storeyInfo
,
int
port
,
List
<
Integer
>
deviceIds
)
{
return
CompletableFuture
.
runAsync
(()
->
{
String
ip
=
storeyInfo
.
getfIp
();
String
storeyIdStr
=
storeyInfo
.
getfStoreyId
().
toString
();
log
.
info
(
"开始端口通信: ip={}, port={}, 设备数={}"
,
ip
,
port
,
deviceIds
.
size
());
AtomicInteger
errorCount
=
new
AtomicInteger
(
0
);
// 并行处理该端口的所有设备
List
<
CompletableFuture
<
Boolean
>>
deviceFutures
=
deviceIds
.
stream
()
.
map
(
deviceId
->
processDeviceWithWrite
(
ip
,
port
,
deviceId
,
errorCount
))
.
collect
(
Collectors
.
toList
());
try
{
// 等待该端口所有设备完成
CompletableFuture
<
Void
>
allDevices
=
CompletableFuture
.
allOf
(
deviceFutures
.
toArray
(
new
CompletableFuture
[
0
])
);
// 端口超时 = 设备数 * 单设备超时 / 并发因子
int
portTimeout
=
Math
.
max
(
30
,
deviceIds
.
size
()
*
SINGLE_DEVICE_TIMEOUT_SEC
/
5
);
allDevices
.
get
(
portTimeout
,
TimeUnit
.
SECONDS
);
}
catch
(
TimeoutException
e
)
{
log
.
warn
(
"端口{}通信超时: ip={}, fStoreyId={}"
,
port
,
ip
,
storeyIdStr
);
recordAlarm
(
storeyInfo
,
"端口"
+
port
+
"通信超时"
);
}
catch
(
Exception
e
)
{
log
.
error
(
"端口{}通信异常: ip={}, fStoreyId={}"
,
port
,
ip
,
storeyIdStr
,
e
);
}
if
(
errorCount
.
get
()
>
0
)
{
log
.
warn
(
"端口{}部分设备失败: 失败数={}, fStoreyId={}"
,
port
,
errorCount
.
get
(),
storeyIdStr
);
}
log
.
info
(
"端口通信完成: ip={}, port={}, fStoreyId={}"
,
ip
,
port
,
storeyIdStr
);
},
GLOBAL_DEVICE_EXECUTOR
);
}
/**
* 处理单个设备(读取 + 条件写入)
*/
private
CompletableFuture
<
Boolean
>
processDeviceWithWrite
(
String
ip
,
int
port
,
int
deviceId
,
AtomicInteger
errorCount
)
{
return
CompletableFuture
.
supplyAsync
(()
->
{
PalletDeviceBinding
binding
;
try
{
// 1. 读取设备数据
int
[]
result
=
Modbus4jUtils
.
readDeviceWithRetry
(
ip
,
port
,
deviceId
);
// 2. 查询设备绑定信息
binding
=
palletDeviceBindingMapper
.
selectByTrayIdAndIndex
(
ip
,
deviceId
);
if
(
binding
==
null
)
{
log
.
warn
(
"未找到设备绑定: ip={}, deviceId={}"
,
ip
,
deviceId
);
recordAlarm
(
null
,
"ip:"
+
ip
+
",port:"
+
port
+
",deviceId:"
+
deviceId
,
"未找到设备绑定"
);
errorCount
.
incrementAndGet
();
return
false
;
}
// 5. 更新数据库
palletDeviceBindingMapper
.
updatePalletDeviceBinding
(
binding
);
log
.
debug
(
"设备{}处理完成: ip={}, port={}, status={}"
,
deviceId
,
ip
,
port
,
result
[
1
]);
return
true
;
}
catch
(
Exception
e
)
{
log
.
info
(
"设备{}处理异常: ip={}, port={}"
,
deviceId
,
ip
,
port
,
e
);
errorCount
.
incrementAndGet
();
return
false
;
}
},
GLOBAL_DEVICE_EXECUTOR
);
}
/**
* 记录告警(兼容设备信息为空的场景)
*/
private
void
recordAlarm
(
TStoreyInfo
storeyInfo
,
String
equipmentCode
,
String
alarmData
)
{
try
{
TEquipmentAlarmData
alarm
=
new
TEquipmentAlarmData
();
alarm
.
setfAlarmType
(
"03"
);
// 老化层告警
alarm
.
setfEquipmentCode
(
storeyInfo
!=
null
?
storeyInfo
.
getfStoreyCode
()
:
equipmentCode
);
alarm
.
setfAlarmData
(
alarmData
);
alarm
.
setfCreateTime
(
new
Date
());
alarmDataService
.
insertTEquipmentAlarmData
(
alarm
);
log
.
debug
(
"告警记录成功:设备编码={},内容={}"
,
alarm
.
getfEquipmentCode
(),
alarmData
);
}
catch
(
Exception
e
)
{
log
.
error
(
"告警记录失败:设备编码={},内容={}"
,
equipmentCode
,
alarmData
,
e
);
}
}
// 辅助方法:记录告警(抽离,避免代码重复)
// 辅助方法:记录告警(抽离,避免代码重复)
private
void
recordAlarm
(
TStoreyInfo
tStoreyInfo
,
String
alarmMsg
)
{
private
void
recordAlarm
(
TStoreyInfo
tStoreyInfo
,
String
alarmMsg
)
{
try
{
try
{
...
@@ -198,7 +327,7 @@ public class FinalExecutionJob implements Job {
...
@@ -198,7 +327,7 @@ public class FinalExecutionJob implements Job {
// 10 层
// 10 层
ModbusMaster
master
;
ModbusMaster
master
;
try
{
try
{
master
=
Modbus4jUtils
.
get
Master
(
fPowerOutageIp
,
fPowerOutagePort
);
master
=
Modbus4jUtils
.
createModbus
Master
(
fPowerOutageIp
,
fPowerOutagePort
);
Boolean
aBoolean
=
Modbus4jUtils
.
writeCoil
(
master
,
1
,
registerOffsets
,
false
);
Boolean
aBoolean
=
Modbus4jUtils
.
writeCoil
(
master
,
1
,
registerOffsets
,
false
);
}
catch
(
ModbusInitException
|
ModbusTransportException
e
)
{
}
catch
(
ModbusInitException
|
ModbusTransportException
e
)
{
throw
new
RuntimeException
(
e
);
throw
new
RuntimeException
(
e
);
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/task/PrepareFinalExecutionJob.java
View file @
79410fee
package
com
.
zehong
.
system
.
task
;
package
com
.
zehong
.
system
.
task
;
import
com.serotonin.modbus4j.ModbusFactory
;
import
com.serotonin.modbus4j.ModbusMaster
;
import
com.serotonin.modbus4j.ModbusMaster
;
import
com.serotonin.modbus4j.exception.ModbusInitException
;
import
com.serotonin.modbus4j.exception.ModbusTransportException
;
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.PalletDeviceBinding
;
import
com.zehong.system.domain.SysRealTimeAdRange
;
import
com.zehong.system.domain.SysRealTimeAdRange
;
import
com.zehong.system.domain.TEquipmentAlarmData
;
import
com.zehong.system.domain.TEquipmentAlarmData
;
...
@@ -16,11 +9,13 @@ import com.zehong.system.domain.TStoreyInfo;
...
@@ -16,11 +9,13 @@ import com.zehong.system.domain.TStoreyInfo;
import
com.zehong.system.mapper.PalletDeviceBindingMapper
;
import
com.zehong.system.mapper.PalletDeviceBindingMapper
;
import
com.zehong.system.mapper.SysRealTimeAdRangeMapper
;
import
com.zehong.system.mapper.SysRealTimeAdRangeMapper
;
import
com.zehong.system.mapper.TStoreyInfoMapper
;
import
com.zehong.system.mapper.TStoreyInfoMapper
;
import
com.zehong.system.modbus.handler.ModbusResultHandler
;
import
com.zehong.system.modbus.util.Modbus4jUtils
;
import
com.zehong.system.modbus.util.Modbus4jUtils
;
import
com.zehong.system.service.ITEquipmentAlarmDataService
;
import
com.zehong.system.service.ITEquipmentAlarmDataService
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.quartz.*
;
import
org.quartz.DisallowConcurrentExecution
;
import
org.quartz.Job
;
import
org.quartz.JobDataMap
;
import
org.quartz.JobExecutionContext
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.stereotype.Component
;
import
org.springframework.stereotype.Component
;
...
@@ -48,12 +43,7 @@ public class PrepareFinalExecutionJob implements Job {
...
@@ -48,12 +43,7 @@ public class PrepareFinalExecutionJob implements Job {
// 超时控制:必须小于Cron周期(假设Cron为5分钟,这里留1分钟缓冲)
// 超时控制:必须小于Cron周期(假设Cron为5分钟,这里留1分钟缓冲)
private
static
final
int
TOTAL_TASK_TIMEOUT_SEC
=
240
;
// 任务总超时:4分钟
private
static
final
int
TOTAL_TASK_TIMEOUT_SEC
=
240
;
// 任务总超时:4分钟
private
static
final
int
SINGLE_DEVICE_TIMEOUT_SEC
=
10
;
// 单个设备超时:10秒
private
static
final
int
SINGLE_DEVICE_TIMEOUT_SEC
=
10
;
// 单个设备超时:10秒
// Modbus配置:取消内置重试,统一用自定义重试
private
static
final
int
MODBUS_CONN_TIMEOUT_MS
=
3000
;
// 连接超时:3秒
private
static
final
int
CUSTOM_RETRY_TIMES
=
2
;
// 自定义重试次数:1次
private
static
final
int
CUSTOM_RETRY_TIMES
=
2
;
// 自定义重试次数:1次
// Modbus寄存器配置
private
static
final
int
REG_START_ADDR
=
0
;
private
static
final
int
REG_READ_COUNT
=
10
;
// 全局线程池 - 避免重复创建
// 全局线程池 - 避免重复创建
private
static
final
ExecutorService
GLOBAL_DEVICE_EXECUTOR
=
new
ThreadPoolExecutor
(
private
static
final
ExecutorService
GLOBAL_DEVICE_EXECUTOR
=
new
ThreadPoolExecutor
(
...
@@ -62,9 +52,6 @@ public class PrepareFinalExecutionJob implements Job {
...
@@ -62,9 +52,6 @@ public class PrepareFinalExecutionJob implements Job {
r
->
new
Thread
(
r
,
"prepare-global-modbus-device"
),
r
->
new
Thread
(
r
,
"prepare-global-modbus-device"
),
new
ThreadPoolExecutor
.
CallerRunsPolicy
()
new
ThreadPoolExecutor
.
CallerRunsPolicy
()
);
);
// 工厂(单例)
private
static
final
ModbusFactory
modbusFactory
=
new
ModbusFactory
();
// -------------------------- 依赖注入 --------------------------
// -------------------------- 依赖注入 --------------------------
@Resource
@Resource
private
ITEquipmentAlarmDataService
alarmDataService
;
private
ITEquipmentAlarmDataService
alarmDataService
;
...
@@ -85,6 +72,11 @@ public class PrepareFinalExecutionJob implements Job {
...
@@ -85,6 +72,11 @@ public class PrepareFinalExecutionJob implements Job {
try
{
try
{
TStoreyInfo
storeyInfo
=
validateAndGetStoreyInfo
(
storeyIdStr
);
TStoreyInfo
storeyInfo
=
validateAndGetStoreyInfo
(
storeyIdStr
);
if
(
storeyInfo
==
null
)
{
log
.
info
(
"无效的storeyId: {}"
,
storeyIdStr
);
recordAlarm
(
null
,
storeyIdStr
,
"PrepareFinalExecutionJob无效的storeyId"
);
return
;
}
// 并行处理3个端口
// 并行处理3个端口
List
<
CompletableFuture
<
Void
>>
portFutures
=
Arrays
.
asList
(
List
<
CompletableFuture
<
Void
>>
portFutures
=
Arrays
.
asList
(
...
@@ -100,14 +92,14 @@ public class PrepareFinalExecutionJob implements Job {
...
@@ -100,14 +92,14 @@ public class PrepareFinalExecutionJob implements Job {
allPorts
.
get
(
TOTAL_TASK_TIMEOUT_SEC
,
TimeUnit
.
SECONDS
);
allPorts
.
get
(
TOTAL_TASK_TIMEOUT_SEC
,
TimeUnit
.
SECONDS
);
log
.
info
(
"任务执行成功: fStoreyId={}, 耗时={}ms"
,
log
.
info
(
"
PrepareFinalExecutionJob
任务执行成功: fStoreyId={}, 耗时={}ms"
,
storeyIdStr
,
System
.
currentTimeMillis
()
-
startTime
);
storeyIdStr
,
System
.
currentTimeMillis
()
-
startTime
);
}
catch
(
TimeoutException
e
)
{
}
catch
(
TimeoutException
e
)
{
log
.
warn
(
"任务执行超时: fStoreyId={}"
,
storeyIdStr
);
log
.
info
(
"任务执行超时: fStoreyId={}"
,
storeyIdStr
);
recordAlarm
(
null
,
storeyIdStr
,
"任务执行超时"
);
recordAlarm
(
null
,
storeyIdStr
,
"任务执行超时"
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
log
.
error
(
"任务执行异常: fStoreyId={}"
,
storeyIdStr
,
e
);
log
.
info
(
"任务执行异常: fStoreyId={}"
,
storeyIdStr
,
e
);
recordAlarm
(
null
,
storeyIdStr
,
"任务执行异常: "
+
e
.
getMessage
());
recordAlarm
(
null
,
storeyIdStr
,
"任务执行异常: "
+
e
.
getMessage
());
}
}
}
}
...
@@ -163,7 +155,7 @@ public class PrepareFinalExecutionJob implements Job {
...
@@ -163,7 +155,7 @@ public class PrepareFinalExecutionJob implements Job {
PalletDeviceBinding
binding
=
null
;
PalletDeviceBinding
binding
=
null
;
try
{
try
{
// 1. 读取设备数据
// 1. 读取设备数据
int
[]
result
=
readDeviceWithRetry
(
ip
,
port
,
deviceId
);
int
[]
result
=
Modbus4jUtils
.
readDeviceWithRetry
(
ip
,
port
,
deviceId
);
// 2. 查询设备绑定信息
// 2. 查询设备绑定信息
binding
=
palletDeviceBindingMapper
.
selectByTrayIdAndIndex
(
ip
,
deviceId
);
binding
=
palletDeviceBindingMapper
.
selectByTrayIdAndIndex
(
ip
,
deviceId
);
...
@@ -193,7 +185,7 @@ public class PrepareFinalExecutionJob implements Job {
...
@@ -193,7 +185,7 @@ public class PrepareFinalExecutionJob implements Job {
// 4. 条件写入时间
// 4. 条件写入时间
if
(
result
[
1
]
==
1
||
result
[
1
]
==
3
||
result
[
1
]
==
4
)
{
if
(
result
[
1
]
==
1
||
result
[
1
]
==
3
||
result
[
1
]
==
4
)
{
// 重用之前的master连接进行写操作
// 重用之前的master连接进行写操作
master
=
createModbusMaster
(
ip
,
port
);
master
=
Modbus4jUtils
.
createModbusMaster
(
ip
,
port
);
checkAndUpdateTime
(
master
,
deviceId
,
binding
);
checkAndUpdateTime
(
master
,
deviceId
,
binding
);
}
else
{
}
else
{
binding
.
setStatus
(
result
[
1
]
+
""
);
binding
.
setStatus
(
result
[
1
]
+
""
);
...
@@ -217,7 +209,7 @@ public class PrepareFinalExecutionJob implements Job {
...
@@ -217,7 +209,7 @@ public class PrepareFinalExecutionJob implements Job {
errorCount
.
incrementAndGet
();
errorCount
.
incrementAndGet
();
return
false
;
return
false
;
}
finally
{
}
finally
{
destroyModbusMaster
(
master
,
deviceId
);
Modbus4jUtils
.
destroyModbusMaster
(
master
,
deviceId
);
}
}
},
GLOBAL_DEVICE_EXECUTOR
);
},
GLOBAL_DEVICE_EXECUTOR
);
}
}
...
@@ -248,65 +240,6 @@ public class PrepareFinalExecutionJob implements Job {
...
@@ -248,65 +240,6 @@ public class PrepareFinalExecutionJob implements Job {
}
}
}
}
/**
* 带重试的设备读取
*/
private
int
[]
readDeviceWithRetry
(
String
ip
,
int
port
,
int
deviceId
)
{
ModbusMaster
master
=
null
;
int
[]
lastResult
=
null
;
// 用于记录最后一次读取的结果(无论是否满足停止条件)
try
{
// 只创建一次ModbusMaster,循环内复用
master
=
createModbusMaster
(
ip
,
port
);
for
(
int
retry
=
0
;
retry
<=
CUSTOM_RETRY_TIMES
;
retry
++)
{
try
{
// 执行读取操作,获取本次结果
int
[]
currentResult
=
readDeviceRegisters
(
master
,
deviceId
);
// 更新最后一次结果(无论是否满足停止条件,都记录)
lastResult
=
currentResult
;
// 检查停止条件,如果满足则提前返回(无需等到重试耗尽)
if
(
ModbusResultHandler
.
createDefaultStopCondition
().
test
(
currentResult
))
{
log
.
info
(
"设备{}第{}次读取成功(满足条件): ip={}, port={}"
,
deviceId
,
retry
+
1
,
ip
,
port
);
return
currentResult
;
}
// 未满足条件且不是最后一次重试,休眠后继续
if
(
retry
<
CUSTOM_RETRY_TIMES
)
{
log
.
info
(
"设备{}第{}次读取未满足条件,准备重试: ip={}, port={}"
,
deviceId
,
retry
+
1
,
ip
,
port
);
Thread
.
sleep
(
200
);
}
}
catch
(
Exception
e
)
{
// 本次读取发生异常,记录日志但不中断重试(继续下一次)
log
.
warn
(
"设备{}第{}次读取发生异常: ip={}, port={}"
,
deviceId
,
retry
+
1
,
ip
,
port
,
e
);
// 如果是最后一次重试,异常时lastResult可能为null(需后续处理)
}
}
// 循环结束(重试耗尽),此时lastResult为最后一次的结果(可能是正常读取但不满足条件,或null)
log
.
info
(
"设备{}重试次数耗尽,返回最后一次结果: ip={}, port={}"
,
deviceId
,
ip
,
port
);
}
catch
(
Exception
e
)
{
// 捕获创建ModbusMaster或休眠时的异常(非读取操作的异常)
log
.
error
(
"设备{}连接创建或休眠失败: ip={}, port={}"
,
deviceId
,
ip
,
port
,
e
);
throw
new
RuntimeException
(
"设备连接或操作异常"
,
e
);
}
finally
{
// 无论结果如何,最终销毁连接
destroyModbusMaster
(
master
,
deviceId
);
}
// 处理最后一次结果可能为null的情况(例如所有重试都异常)
if
(
lastResult
==
null
)
{
throw
new
RuntimeException
(
"设备所有读取尝试均失败(无有效结果)"
);
}
return
lastResult
;
}
/**
/**
* 检查并更新时间
* 检查并更新时间
*/
*/
...
@@ -514,58 +447,6 @@ public class PrepareFinalExecutionJob implements Job {
...
@@ -514,58 +447,6 @@ public class PrepareFinalExecutionJob implements Job {
recordAlarmByBinding
(
binding
,
"设备时间写入异常: "
+
e
.
getMessage
());
recordAlarmByBinding
(
binding
,
"设备时间写入异常: "
+
e
.
getMessage
());
}
}
}
}
// -------------------------- Modbus工具方法(显式抛出异常)--------------------------
/**
* 创建Modbus连接(取消内置重试,统一自定义重试)
*/
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
.
init
();
return
master
;
}
/**
* 读取设备寄存器(异常直接抛出)
*/
private
int
[]
readDeviceRegisters
(
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
))
{
log
.
info
(
"无效Modbus响应类型:"
+
response
.
getClass
().
getName
()
+
",deviceId="
+
deviceId
);
}
assert
response
instanceof
ReadHoldingRegistersResponse
;
ReadHoldingRegistersResponse
regResp
=
(
ReadHoldingRegistersResponse
)
response
;
short
[]
signedVals
=
regResp
.
getShortData
();
int
[]
unsignedVals
=
new
int
[
signedVals
.
length
];
for
(
int
i
=
0
;
i
<
signedVals
.
length
;
i
++)
{
unsignedVals
[
i
]
=
signedVals
[
i
]
&
0xFFFF
;
// 转换为无符号整数
}
log
.
info
(
"设备寄存器读取结果:deviceId={},值={}"
,
deviceId
,
Arrays
.
toString
(
unsignedVals
));
return
unsignedVals
;
}
/**
* 销毁Modbus连接(反射失败直接抛出异常,显式暴露问题)
*/
private
void
destroyModbusMaster
(
ModbusMaster
master
,
int
deviceId
)
{
if
(
master
!=
null
)
{
try
{
master
.
destroy
();
}
catch
(
Exception
e
)
{
log
.
debug
(
"设备{}: ModbusMaster销毁异常"
,
deviceId
,
e
);
}
}
}
// -------------------------- 辅助方法(日志/告警)--------------------------
// -------------------------- 辅助方法(日志/告警)--------------------------
/**
/**
...
...
zhmes-agecal-system/src/main/resources/mapper/system/PalletDeviceBindingMapper.xml
View file @
79410fee
...
@@ -36,6 +36,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
...
@@ -36,6 +36,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result
property=
"calibrationConcentration"
column=
"f_calibration_concentration"
/>
<result
property=
"calibrationConcentration"
column=
"f_calibration_concentration"
/>
<result
property=
"calibrationConcentrationStatus"
column=
"f_calibration_concentration_status"
/>
<result
property=
"calibrationConcentrationStatus"
column=
"f_calibration_concentration_status"
/>
<result
property=
"writeSelfCheckStatus"
column=
"f_write_self_check_status"
/>
<result
property=
"relayStatus"
column=
"f_relay_status"
/>
<result
property=
"pulseStatus"
column=
"f_pulse_status"
/>
<result
property=
"moduleStatus"
column=
"f_module_status"
/>
<result
property=
"simCardStatus"
column=
"f_sim_card_status"
/>
<result
property=
"networkStatus"
column=
"f_network_status"
/>
</resultMap>
</resultMap>
<sql
id=
"selectPalletDeviceBindingVo"
>
<sql
id=
"selectPalletDeviceBindingVo"
>
...
@@ -66,7 +73,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
...
@@ -66,7 +73,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
palDeviceBinding.f_real_time_ad,
palDeviceBinding.f_real_time_ad,
palDeviceBinding.f_real_time_ad_status,
palDeviceBinding.f_real_time_ad_status,
palDeviceBinding.f_calibration_concentration,
palDeviceBinding.f_calibration_concentration,
palDeviceBinding.f_calibration_concentration_status
palDeviceBinding.f_calibration_concentration_status,
palDeviceBinding.f_write_self_check_status,
palDeviceBinding.f_relay_status,
palDeviceBinding.f_pulse_status,
palDeviceBinding.f_module_status,
palDeviceBinding.f_sim_card_status,
palDeviceBinding.f_network_status
from t_pallet_device_binding palDeviceBinding
from t_pallet_device_binding palDeviceBinding
left join t_tray_info trayInfo on trayInfo.f_tray_id = palDeviceBinding.f_tray_id
left join t_tray_info trayInfo on trayInfo.f_tray_id = palDeviceBinding.f_tray_id
</sql>
</sql>
...
@@ -144,7 +157,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
...
@@ -144,7 +157,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
f_real_time_ad,
f_real_time_ad,
f_real_time_ad_status,
f_real_time_ad_status,
f_calibration_concentration,
f_calibration_concentration,
f_calibration_concentration_status
f_calibration_concentration_status,
f_write_self_check_status,
f_relay_status,
f_pulse_status,
f_module_status,
f_sim_card_status,
f_network_status
from t_pallet_device_binding palDeviceBinding where palDeviceBinding.f_tray_id = (
from t_pallet_device_binding palDeviceBinding where palDeviceBinding.f_tray_id = (
SELECT
SELECT
trayInfo.f_tray_id
trayInfo.f_tray_id
...
@@ -203,7 +222,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
...
@@ -203,7 +222,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
f_real_time_ad = null,
f_real_time_ad = null,
f_real_time_ad_status = null,
f_real_time_ad_status = null,
f_calibration_concentration = null,
f_calibration_concentration = null,
f_calibration_concentration_status = null
f_calibration_concentration_status = null,
f_write_self_check_status = null,
f_relay_status = null,
f_pulse_status = null,
f_module_status = null,
f_sim_card_status = null,
f_network_status = null
where f_tray_id = #{trayId}
where f_tray_id = #{trayId}
</update>
</update>
<insert
id=
"insertPalletDeviceBinding"
parameterType=
"PalletDeviceBinding"
useGeneratedKeys=
"true"
keyProperty=
"palletDeviceBindingId"
>
<insert
id=
"insertPalletDeviceBinding"
parameterType=
"PalletDeviceBinding"
useGeneratedKeys=
"true"
keyProperty=
"palletDeviceBindingId"
>
...
@@ -254,7 +279,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
...
@@ -254,7 +279,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
f_real_time_ad = null,
f_real_time_ad = null,
f_real_time_ad_status = null,
f_real_time_ad_status = null,
f_calibration_concentration = null,
f_calibration_concentration = null,
f_calibration_concentration_status = null
f_calibration_concentration_status = null,
f_write_self_check_status = null,
f_relay_status = null,
f_pulse_status = null,
f_module_status = null,
f_sim_card_status = null,
f_network_status = null
where f_pallet_device_binding_id = #{palletDeviceBindingId}
where f_pallet_device_binding_id = #{palletDeviceBindingId}
</update>
</update>
<update
id=
"updatePalletDeviceBinding"
parameterType=
"PalletDeviceBinding"
>
<update
id=
"updatePalletDeviceBinding"
parameterType=
"PalletDeviceBinding"
>
...
@@ -289,6 +320,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
...
@@ -289,6 +320,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if
test=
"calibrationConcentration != null"
>
f_calibration_concentration = #{calibrationConcentration},
</if>
<if
test=
"calibrationConcentration != null"
>
f_calibration_concentration = #{calibrationConcentration},
</if>
<if
test=
"calibrationConcentrationStatus != null"
>
f_calibration_concentration_status = #{calibrationConcentrationStatus},
</if>
<if
test=
"calibrationConcentrationStatus != null"
>
f_calibration_concentration_status = #{calibrationConcentrationStatus},
</if>
<if
test=
"writeSelfCheckStatus != null"
>
f_write_self_check_status = #{writeSelfCheckStatus},
</if>
<if
test=
"relayStatus != null"
>
f_relay_status = #{relayStatus},
</if>
<if
test=
"pulseStatus != null"
>
f_pulse_status = #{pulseStatus},
</if>
<if
test=
"moduleStatus != null"
>
f_module_status = #{moduleStatus},
</if>
<if
test=
"simCardStatus != null"
>
f_sim_card_status = #{simCardStatus},
</if>
<if
test=
"networkStatus != null"
>
f_network_status = #{networkStatus},
</if>
</trim>
</trim>
where f_pallet_device_binding_id = #{palletDeviceBindingId}
where f_pallet_device_binding_id = #{palletDeviceBindingId}
</update>
</update>
...
@@ -338,7 +375,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
...
@@ -338,7 +375,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
f_real_time_ad = null,
f_real_time_ad = null,
f_real_time_ad_status = null,
f_real_time_ad_status = null,
f_calibration_concentration = null,
f_calibration_concentration = null,
f_calibration_concentration_status = null
f_calibration_concentration_status = null,
f_write_self_check_status = null,
f_relay_status = null,
f_pulse_status = null,
f_module_status = null,
f_sim_card_status = null,
f_network_status = null
<choose>
<choose>
<when
test=
"item.deviceCode != null"
>
<when
test=
"item.deviceCode != null"
>
, f_device_code = #{item.deviceCode}
, f_device_code = #{item.deviceCode}
...
@@ -369,7 +412,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
...
@@ -369,7 +412,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
f_real_time_ad = null,
f_real_time_ad = null,
f_real_time_ad_status = null,
f_real_time_ad_status = null,
f_calibration_concentration = null,
f_calibration_concentration = null,
f_calibration_concentration_status = null
f_calibration_concentration_status = null,
f_write_self_check_status = null,
f_relay_status = null,
f_pulse_status = null,
f_module_status = null,
f_sim_card_status = null,
f_network_status = null
where f_tray_id = #{trayId}
where f_tray_id = #{trayId}
</update>
</update>
...
...
zhmes-agecal-system/src/main/resources/mapper/system/PalletDeviceUploadHistoryMapper.xml
View file @
79410fee
...
@@ -33,6 +33,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
...
@@ -33,6 +33,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result
property=
"calibrationConcentration"
column=
"f_calibration_concentration"
/>
<result
property=
"calibrationConcentration"
column=
"f_calibration_concentration"
/>
<result
property=
"calibrationConcentrationStatus"
column=
"f_calibration_concentration_status"
/>
<result
property=
"calibrationConcentrationStatus"
column=
"f_calibration_concentration_status"
/>
<result
property=
"writeSelfCheckStatus"
column=
"f_write_self_check_status"
/>
<result
property=
"relayStatus"
column=
"f_relay_status"
/>
<result
property=
"pulseStatus"
column=
"f_pulse_status"
/>
<result
property=
"moduleStatus"
column=
"f_module_status"
/>
<result
property=
"simCardStatus"
column=
"f_sim_card_status"
/>
<result
property=
"networkStatus"
column=
"f_network_status"
/>
</resultMap>
</resultMap>
<sql
id=
"selectPalletDeviceUploadHistoryVo"
>
<sql
id=
"selectPalletDeviceUploadHistoryVo"
>
...
@@ -63,7 +70,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
...
@@ -63,7 +70,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
palDeviceBinding.f_real_time_ad,
palDeviceBinding.f_real_time_ad,
palDeviceBinding.f_real_time_ad_status,
palDeviceBinding.f_real_time_ad_status,
palDeviceBinding.f_calibration_concentration,
palDeviceBinding.f_calibration_concentration,
palDeviceBinding.f_calibration_concentration_status
palDeviceBinding.f_calibration_concentration_status,
palDeviceBinding.f_write_self_check_status,
palDeviceBinding.f_relay_status,
palDeviceBinding.f_pulse_status,
palDeviceBinding.f_module_status,
palDeviceBinding.f_sim_card_status,
palDeviceBinding.f_network_status
from t_pallet_device_upload_history palDeviceBinding
from t_pallet_device_upload_history palDeviceBinding
left join t_tray_info trayInfo on trayInfo.f_tray_id = palDeviceBinding.f_tray_id
left join t_tray_info trayInfo on trayInfo.f_tray_id = palDeviceBinding.f_tray_id
</sql>
</sql>
...
@@ -108,7 +121,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
...
@@ -108,7 +121,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
f_real_time_ad,
f_real_time_ad,
f_real_time_ad_status,
f_real_time_ad_status,
f_calibration_concentration,
f_calibration_concentration,
f_calibration_concentration_status
f_calibration_concentration_status,
f_write_self_check_status,
f_relay_status,
f_pulse_status,
f_module_status,
f_sim_card_status,
f_network_status
</trim>
</trim>
values
values
<foreach
collection=
"list"
item=
"item"
separator=
","
>
<foreach
collection=
"list"
item=
"item"
separator=
","
>
...
@@ -138,7 +157,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
...
@@ -138,7 +157,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{item.realTimeAd},
#{item.realTimeAd},
#{item.realTimeAdStatus},
#{item.realTimeAdStatus},
#{item.calibrationConcentration},
#{item.calibrationConcentration},
#{item.calibrationConcentrationStatus}
#{item.calibrationConcentrationStatus},
#{item.writeSelfCheckStatus},
#{item.relayStatus},
#{item.pulseStatus},
#{item.moduleStatus},
#{item.simCardStatus},
#{item.networkStatus}
</trim>
</trim>
</foreach>
</foreach>
</insert>
</insert>
...
@@ -171,6 +196,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
...
@@ -171,6 +196,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if
test=
"realTimeAdStatus != null"
>
f_real_time_ad_status,
</if>
<if
test=
"realTimeAdStatus != null"
>
f_real_time_ad_status,
</if>
<if
test=
"calibrationConcentration != null"
>
#{calibrationConcentration},
</if>
<if
test=
"calibrationConcentration != null"
>
#{calibrationConcentration},
</if>
<if
test=
"calibrationConcentrationStatus != null"
>
#{calibrationConcentrationStatus},
</if>
<if
test=
"calibrationConcentrationStatus != null"
>
#{calibrationConcentrationStatus},
</if>
<if
test=
"writeSelfCheckStatus != null"
>
#{writeSelfCheckStatus},
</if>
<if
test=
"relayStatus != null"
>
#{relayStatus},
</if>
<if
test=
"pulseStatus != null"
>
#{pulseStatus},
</if>
<if
test=
"moduleStatus != null"
>
#{moduleStatus},
</if>
<if
test=
"simCardStatus != null"
>
#{simCardStatus},
</if>
<if
test=
"networkStatus != null"
>
#{networkStatus},
</if>
</trim>
</trim>
<trim
prefix=
"values ("
suffix=
")"
suffixOverrides=
","
>
<trim
prefix=
"values ("
suffix=
")"
suffixOverrides=
","
>
<if
test=
"trayId != null"
>
#{trayId},
</if>
<if
test=
"trayId != null"
>
#{trayId},
</if>
...
@@ -199,6 +231,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
...
@@ -199,6 +231,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if
test=
"realTimeAdStatus != null"
>
#{realTimeAdStatus},
</if>
<if
test=
"realTimeAdStatus != null"
>
#{realTimeAdStatus},
</if>
<if
test=
"calibrationConcentration != null"
>
#{calibrationConcentration},
</if>
<if
test=
"calibrationConcentration != null"
>
#{calibrationConcentration},
</if>
<if
test=
"calibrationConcentrationStatus != null"
>
#{calibrationConcentrationStatus},
</if>
<if
test=
"calibrationConcentrationStatus != null"
>
#{calibrationConcentrationStatus},
</if>
<if
test=
"writeSelfCheckStatus != null"
>
#{writeSelfCheckStatus},
</if>
<if
test=
"relayStatus != null"
>
#{relayStatus},
</if>
<if
test=
"pulseStatus != null"
>
#{pulseStatus},
</if>
<if
test=
"moduleStatus != null"
>
#{moduleStatus},
</if>
<if
test=
"simCardStatus != null"
>
#{simCardStatus},
</if>
<if
test=
"networkStatus != null"
>
#{networkStatus},
</if>
</trim>
</trim>
</insert>
</insert>
...
@@ -231,6 +270,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
...
@@ -231,6 +270,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if
test=
"realTimeAdStatus != null"
>
f_real_time_ad_status = #{realTimeAdStatus},
</if>
<if
test=
"realTimeAdStatus != null"
>
f_real_time_ad_status = #{realTimeAdStatus},
</if>
<if
test=
"calibrationConcentration != null"
>
f_calibration_concentration = #{calibrationConcentration},
</if>
<if
test=
"calibrationConcentration != null"
>
f_calibration_concentration = #{calibrationConcentration},
</if>
<if
test=
"calibrationConcentrationStatus != null"
>
f_calibration_concentration_status = #{calibrationConcentrationStatus},
</if>
<if
test=
"calibrationConcentrationStatus != null"
>
f_calibration_concentration_status = #{calibrationConcentrationStatus},
</if>
<if
test=
"writeSelfCheckStatus != null"
>
f_write_self_check_status = #{writeSelfCheckStatus},
</if>
<if
test=
"relayStatus != null"
>
f_relay_status = #{relayStatus},
</if>
<if
test=
"pulseStatus != null"
>
f_pulse_status = #{pulseStatus},
</if>
<if
test=
"moduleStatus != null"
>
f_module_status = #{moduleStatus},
</if>
<if
test=
"simCardStatus != null"
>
f_sim_card_status = #{simCardStatus},
</if>
<if
test=
"networkStatus != null"
>
f_network_status = #{networkStatus},
</if>
</trim>
</trim>
where f_id = #{id}
where f_id = #{id}
</update>
</update>
...
...
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