|
|
@@ -1,6 +1,5 @@
|
|
|
package com.jeesite.modules.scheduling;
|
|
|
|
|
|
-import com.github.xingshuangs.iot.protocol.common.buff.EByteBuffFormat;
|
|
|
import com.github.xingshuangs.iot.protocol.modbus.service.ModbusTcp;
|
|
|
import com.jeesite.common.config.Global;
|
|
|
import com.jeesite.common.lang.ObjectUtils;
|
|
|
@@ -94,7 +93,10 @@ public class FswModbusScheduling {
|
|
|
|
|
|
private final AtomicBoolean running = new AtomicBoolean(false);
|
|
|
private volatile ModbusTcp modbusTcp;
|
|
|
+ /** 质量校验去重:同一工件码不重复校验 */
|
|
|
private volatile String lastCheckedSn;
|
|
|
+ /** 最近一次非空工件码(采集时 PLC 可能已清空 3620,用此兜底) */
|
|
|
+ private volatile String lastKnownSn;
|
|
|
|
|
|
/**
|
|
|
* 每秒执行:工件码质量校验 + 过程参数采集握手
|
|
|
@@ -135,14 +137,67 @@ public class FswModbusScheduling {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * 强制采集并落库(供测试):不检查 4740 / 3600,直接读过程参数写入 mes_product_fsw。
|
|
|
+ *
|
|
|
+ * @param snOverride 指定工件码;为空则从 3620 读取,仍为空则用最近缓存
|
|
|
+ * @param clearFlag3600 落库成功后是否将 3600 置 0
|
|
|
+ * @param updateStation 是否同步将 OP230B 工位结果置 OK
|
|
|
+ * @return true=过程参数已写入表
|
|
|
+ */
|
|
|
+ public boolean collectAndSaveNow(String snOverride, boolean clearFlag3600, boolean updateStation) {
|
|
|
+ if (!running.compareAndSet(false, true)) {
|
|
|
+ logger.warn("FSW Modbus上一轮尚未结束,跳过强制采集");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ ModbusTcp plc = getClient();
|
|
|
+ String sn = StringUtils.isNotBlank(snOverride) ? snOverride.trim() : readWorkpieceCode(plc);
|
|
|
+ if (StringUtils.isBlank(sn)) {
|
|
|
+ sn = lastKnownSn;
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(sn)) {
|
|
|
+ logger.error("强制采集失败:无工件码(可在测试类 FORCE_SN 指定)");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ lastKnownSn = sn;
|
|
|
+
|
|
|
+ short feedSpeed = plc.readInt16(ADDR_FEED_SPEED);
|
|
|
+ short feedRate = plc.readInt16(ADDR_FEED_RATE);
|
|
|
+ short spindleSpeed = plc.readInt16(ADDR_SPINDLE_SPEED);
|
|
|
+ short spindleRate = plc.readInt16(ADDR_SPINDLE_RATE);
|
|
|
+ short weldPressure = plc.readInt16(ADDR_WELD_PRESSURE);
|
|
|
+ short weldOffset = plc.readInt16(ADDR_WELD_OFFSET);
|
|
|
+ short bAxisAngle = plc.readInt16(ADDR_B_AXIS_ANGLE);
|
|
|
+
|
|
|
+ logger.info("FSW强制采集 sn={} 进给速度={} 进给倍率={} 主轴转速={} 主轴倍率={} 焊接压力={} 偏移量={} B轴角度={}",
|
|
|
+ sn, feedSpeed, feedRate, spindleSpeed, spindleRate, weldPressure, weldOffset, bAxisAngle);
|
|
|
+
|
|
|
+ boolean ok = saveProcessData(sn, feedSpeed, feedRate, spindleSpeed, spindleRate,
|
|
|
+ weldPressure, weldOffset, bAxisAngle, updateStation);
|
|
|
+ if (ok && clearFlag3600) {
|
|
|
+ plc.writeInt16(ADDR_COLLECT_FLAG, (short) 0);
|
|
|
+ logger.info("FSW强制采集完成,已将 3600 置 0 sn={}", sn);
|
|
|
+ }
|
|
|
+ return ok;
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("FSW强制采集失败:{}", e.getMessage(), e);
|
|
|
+ closeClient();
|
|
|
+ return false;
|
|
|
+ } finally {
|
|
|
+ running.set(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 读取工件码 → 质量校验 → 写回 3610(1合格 / 2不合格)
|
|
|
*/
|
|
|
private void handleQualityCheck(ModbusTcp plc) {
|
|
|
String sn = readWorkpieceCode(plc);
|
|
|
if (StringUtils.isBlank(sn)) {
|
|
|
- lastCheckedSn = null;
|
|
|
+ // 不清空 lastKnownSn:采集触发时寄存器可能已被 PLC 清掉
|
|
|
return;
|
|
|
}
|
|
|
+ lastKnownSn = sn;
|
|
|
if (sn.equals(lastCheckedSn)) {
|
|
|
return;
|
|
|
}
|
|
|
@@ -154,7 +209,7 @@ public class FswModbusScheduling {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 3600=1 时采集过程参数,完成后置 0
|
|
|
+ * 3600=1 时采集过程参数;仅保存成功后才置 0,避免空工件码时丢数却清握手位
|
|
|
*/
|
|
|
private void handleCollectTrigger(ModbusTcp plc) {
|
|
|
Short flag = plc.readInt16(ADDR_COLLECT_FLAG);
|
|
|
@@ -163,19 +218,33 @@ public class FswModbusScheduling {
|
|
|
}
|
|
|
|
|
|
String sn = readWorkpieceCode(plc);
|
|
|
- float feedSpeed = plc.readFloat32(ADDR_FEED_SPEED, EByteBuffFormat.BA_DC);
|
|
|
- float feedRate = plc.readFloat32(ADDR_FEED_RATE, EByteBuffFormat.BA_DC);
|
|
|
- float spindleSpeed = plc.readFloat32(ADDR_SPINDLE_SPEED, EByteBuffFormat.BA_DC);
|
|
|
- float spindleRate = plc.readFloat32(ADDR_SPINDLE_RATE, EByteBuffFormat.BA_DC);
|
|
|
- float weldPressure = plc.readFloat32(ADDR_WELD_PRESSURE, EByteBuffFormat.BA_DC);
|
|
|
- float weldOffset = plc.readFloat32(ADDR_WELD_OFFSET, EByteBuffFormat.BA_DC);
|
|
|
- float bAxisAngle = plc.readFloat32(ADDR_B_AXIS_ANGLE, EByteBuffFormat.BA_DC);
|
|
|
+ if (StringUtils.isBlank(sn)) {
|
|
|
+ sn = lastKnownSn;
|
|
|
+ logger.warn("FSW过程采集:3620 工件码为空,使用最近工件码 sn={}", sn);
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(sn)) {
|
|
|
+ logger.error("FSW过程采集失败:无工件码,保持 3600=1 待重试");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ lastKnownSn = sn;
|
|
|
+
|
|
|
+ short feedSpeed = plc.readInt16(ADDR_FEED_SPEED);
|
|
|
+ short feedRate = plc.readInt16(ADDR_FEED_RATE);
|
|
|
+ short spindleSpeed = plc.readInt16(ADDR_SPINDLE_SPEED);
|
|
|
+ short spindleRate = plc.readInt16(ADDR_SPINDLE_RATE);
|
|
|
+ short weldPressure = plc.readInt16(ADDR_WELD_PRESSURE);
|
|
|
+ short weldOffset = plc.readInt16(ADDR_WELD_OFFSET);
|
|
|
+ short bAxisAngle = plc.readInt16(ADDR_B_AXIS_ANGLE);
|
|
|
|
|
|
logger.info("FSW过程采集 sn={} 进给速度={} 进给倍率={} 主轴转速={} 主轴倍率={} 焊接压力={} 偏移量={} B轴角度={}",
|
|
|
sn, feedSpeed, feedRate, spindleSpeed, spindleRate, weldPressure, weldOffset, bAxisAngle);
|
|
|
|
|
|
- saveProcessData(sn, feedSpeed, feedRate, spindleSpeed, spindleRate, weldPressure, weldOffset, bAxisAngle);
|
|
|
- plc.writeInt16(ADDR_COLLECT_FLAG, (short) 0);
|
|
|
+ if (saveProcessData(sn, feedSpeed, feedRate, spindleSpeed, spindleRate, weldPressure, weldOffset, bAxisAngle, true)) {
|
|
|
+ plc.writeInt16(ADDR_COLLECT_FLAG, (short) 0);
|
|
|
+ logger.info("FSW过程采集完成,已将 3600 置 0 sn={}", sn);
|
|
|
+ } else {
|
|
|
+ logger.error("FSW过程参数保存失败,保持 3600=1 待重试 sn={}", sn);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private boolean doQualityCheck(String sn) {
|
|
|
@@ -225,34 +294,50 @@ public class FswModbusScheduling {
|
|
|
return line.getSn();
|
|
|
}
|
|
|
|
|
|
- private void saveProcessData(String sn, float feedSpeed, float feedRate,
|
|
|
- float spindleSpeed, float spindleRate, float weldPressure, float weldOffset, float bAxisAngle) {
|
|
|
+ /**
|
|
|
+ * @param updateStation true 时同步提交 OP230B 工位结果为 OK
|
|
|
+ * @return true=过程参数已落库(工位结果更新失败不影响返回 true)
|
|
|
+ */
|
|
|
+ private boolean saveProcessData(String sn, short feedSpeed, short feedRate,
|
|
|
+ short spindleSpeed, short spindleRate, short weldPressure, short weldOffset, short bAxisAngle,
|
|
|
+ boolean updateStation) {
|
|
|
if (StringUtils.isBlank(sn)) {
|
|
|
- return;
|
|
|
+ logger.error("FSW过程参数保存跳过:工件码为空");
|
|
|
+ return false;
|
|
|
}
|
|
|
try {
|
|
|
MesProductFsw entity = new MesProductFsw();
|
|
|
entity.setSn(sn);
|
|
|
entity.setOprno(FIXED_OPRNO);
|
|
|
entity.setLineSn(FIXED_LINE_SN);
|
|
|
- entity.setFeedSpeed(fmt(feedSpeed));
|
|
|
- entity.setFeedRate(fmt(feedRate));
|
|
|
- entity.setSpindleSpeed(fmt(spindleSpeed));
|
|
|
- entity.setSpindleRate(fmt(spindleRate));
|
|
|
- entity.setPressure(fmt(weldPressure));
|
|
|
- entity.setPyl(fmt(weldOffset));
|
|
|
- entity.setJd(fmt(bAxisAngle));
|
|
|
+ entity.setFeedSpeed(String.valueOf(feedSpeed));
|
|
|
+ entity.setFeedRate(String.valueOf(feedRate));
|
|
|
+ entity.setSpindleSpeed(String.valueOf(spindleSpeed));
|
|
|
+ entity.setSpindleRate(String.valueOf(spindleRate));
|
|
|
+ entity.setPressure(String.valueOf(weldPressure));
|
|
|
+ entity.setPyl(String.valueOf(weldOffset));
|
|
|
+ entity.setJd(String.valueOf(bAxisAngle));
|
|
|
mesProductFswService.save(entity);
|
|
|
+ logger.info("FSW过程参数已写入 mes_product_fsw sn={} oprno={}", sn, FIXED_OPRNO);
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("FSW过程参数保存失败 sn={}:{}", sn, e.getMessage(), e);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- // 保存完成后提交工位总结果为 OK
|
|
|
+ if (!updateStation) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ try {
|
|
|
List<ParamsResp> params = new ArrayList<>();
|
|
|
List<BindMaterialResp> bmlists = new ArrayList<>();
|
|
|
mesProductRecordService.updateRecordResult(sn, FIXED_OPRNO, "100000", "", "OK",
|
|
|
"", params, FIXED_LINE_SN, true, bmlists, null);
|
|
|
- logger.info("FSW过程参数已保存并更新工位结果 OK sn={} oprno={}", sn, FIXED_OPRNO);
|
|
|
+ logger.info("FSW已更新工位结果 OK sn={} oprno={}", sn, FIXED_OPRNO);
|
|
|
} catch (Exception e) {
|
|
|
- logger.error("FSW过程参数保存失败 sn={}:{}", sn, e.getMessage());
|
|
|
+ // 过程参数已落库,工位结果失败单独记日志,不阻断清 3600
|
|
|
+ logger.error("FSW更新工位结果失败 sn={}:{}", sn, e.getMessage(), e);
|
|
|
}
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -319,8 +404,4 @@ public class FswModbusScheduling {
|
|
|
return defaultVal;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- private static String fmt(float val) {
|
|
|
- return String.format("%.3f", val);
|
|
|
- }
|
|
|
}
|