Commit 79410fee authored by wanghao's avatar wanghao

1 点数数据表 增加 继电器状态 等五个字段 DDL维护。

2 点位数据vo及历史记录vo 及mapper增加 继电器状态 等五个字段。
3 老化最终流程 执行 读取 继电器状态  等5个状态的 操作,待跟硬件对接。
parent 98287cc1
...@@ -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
...@@ -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;
}
} }
...@@ -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();
} }
} }
...@@ -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 +
'}';
} }
} }
...@@ -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);
......
...@@ -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 getMaster(String ip, int port) throws ModbusInitException { public static ModbusMaster createModbusMaster(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 = getMaster("192.168.1.11", 503); master = createModbusMaster("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 = getMaster(ip, port); master = createModbusMaster(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 = getMaster("192.168.2.1", 501); modbusMaster = createModbusMaster("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;
}
/** /**
* 读取设备寄存器(线程安全版) * 读取设备寄存器(线程安全版)
*/ */
......
...@@ -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;
} }
......
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);
}
} }
} }
// -------------------------- 辅助方法(日志/告警)-------------------------- // -------------------------- 辅助方法(日志/告警)--------------------------
......
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.RobotArmCommandMapper; import com.zehong.system.mapper.PalletDeviceBindingMapper;
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.getMaster(fPowerOutageIp, fPowerOutagePort); master = Modbus4jUtils.createModbusMaster(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);
......
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);
}
}
}
// -------------------------- 辅助方法(日志/告警)-------------------------- // -------------------------- 辅助方法(日志/告警)--------------------------
/** /**
......
...@@ -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>
......
...@@ -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>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment