From 9a9479a5e34324822b223747b7c88ff060466db0 Mon Sep 17 00:00:00 2001
From: huang <1532065656@qq.com>
Date: 星期四, 04 十二月 2025 16:58:29 +0800
Subject: [PATCH] 修改任务定时触发大车逻辑,循环检查mes值是否符合
---
mes-processes/mes-plcSend/src/main/java/com/mes/interaction/vehicle/handler/LoadVehicleLogicHandler.java | 991 ++++++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 818 insertions(+), 173 deletions(-)
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/vehicle/handler/LoadVehicleLogicHandler.java b/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/vehicle/handler/LoadVehicleLogicHandler.java
index 4a40192..7a04e23 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/vehicle/handler/LoadVehicleLogicHandler.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/vehicle/handler/LoadVehicleLogicHandler.java
@@ -1,10 +1,12 @@
package com.mes.interaction.vehicle.handler;
import com.mes.device.entity.DeviceConfig;
+import com.mes.device.entity.DeviceStatus;
import com.mes.device.service.DeviceConfigService;
import com.mes.device.service.DeviceGroupRelationService;
import com.mes.device.service.DevicePlcOperationService;
import com.mes.device.service.GlassInfoService;
+import com.mes.device.service.DeviceStatusService;
import com.mes.device.vo.DeviceGroupVO;
import com.mes.device.vo.DevicePlcVO;
import com.mes.interaction.BaseDeviceLogicHandler;
@@ -16,6 +18,8 @@
import com.mes.s7.enhanced.EnhancedS7Serializer;
import com.mes.s7.provider.S7SerializerProvider;
import com.mes.service.PlcDynamicDataService;
+import com.mes.task.model.TaskExecutionContext;
+import com.mes.interaction.workstation.scanner.handler.HorizontalScannerLogicHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -49,15 +53,28 @@
private DeviceGroupRelationService deviceGroupRelationService;
@Autowired(required = false)
+ private DeviceStatusService deviceStatusService;
+
+ @Autowired(required = false)
private PlcDynamicDataService plcDynamicDataService;
@Autowired(required = false)
private S7SerializerProvider s7SerializerProvider;
// MES瀛楁鍒楄〃锛堣繘鐗囧拰鍑虹墖鍏辩敤鍚屼竴濂楀崗璁級
+ // 鏍规嵁鍗忚锛屼娇鐢ㄥ甫鏁板瓧鍚庣紑鐨勫瓧娈靛悕锛�1-6瀵瑰簲6涓幓鐠冧綅缃級
+ // 鏀寔璇诲彇鎵�鏈�6涓幓鐠冪殑淇℃伅
private static final List<String> MES_FIELDS = Arrays.asList(
- "mesSend", "mesGlassId", "mesWidth", "mesHeight",
- "startSlot", "targetSlot", "workLine"
+ "mesSend", "mesConfirm",
+ // 鐜荤拑1-6鐨処D
+ "mesGlassId1", "mesGlassId2", "mesGlassId3", "mesGlassId4", "mesGlassId5", "mesGlassId6",
+ // 鐜荤拑1-6鐨勫昂瀵�
+ "mesWidth1", "mesWidth2", "mesWidth3", "mesWidth4", "mesWidth5", "mesWidth6",
+ "mesHeight1", "mesHeight2", "mesHeight3", "mesHeight4", "mesHeight5", "mesHeight6",
+ "mesThickness1", "mesThickness2", "mesThickness3", "mesThickness4", "mesThickness5", "mesThickness6",
+ // 鐜荤拑1-6鐨勮捣濮嬩綅缃拰鐩爣浣嶇疆
+ "start1", "start2", "start3", "start4", "start5", "start6",
+ "target1", "target2", "target3", "target4", "target5", "target6"
);
// 鐩戞帶绾跨▼姹狅細鐢ㄤ簬瀹氭湡妫�鏌ュぇ杞︾姸鎬佸苟鍗忚皟鍗ц浆绔嬭澶�
@@ -124,14 +141,21 @@
if (needsStateCheck(operation)) {
VehicleStatus status = statusManager.getVehicleStatus(deviceId);
if (status != null && !status.isAvailable()) {
- return DevicePlcVO.OperationResult.builder()
- .success(false)
- .message(String.format("杞﹁締 %s (%s) 褰撳墠鐘舵�佷负 %s锛屾棤娉曟墽琛屾搷浣� %s",
- deviceConfig.getDeviceName(),
- deviceId,
- status.getState(),
- operation))
- .build();
+ // 瀵逛簬 feedGlass 鎿嶄綔锛屽鏋滅姸鎬佹槸 EXECUTING锛屽厑璁哥户缁墽琛�
+ // 鍥犱负瀹氭椂鍣ㄥ彲鑳戒細閲嶅璋冪敤锛屾垨鑰呴渶瑕佺瓑寰呬换鍔″畬鎴�
+ if ("feedGlass".equals(operation) && status.isExecuting()) {
+ log.debug("杞﹁締 {} 褰撳墠鐘舵�佷负 EXECUTING锛屼絾鍏佽缁х画鎵ц feedGlass锛堝畾鏃跺櫒閲嶅璋冪敤锛�", deviceId);
+ // 鍏佽缁х画鎵ц锛屼笉杩斿洖閿欒
+ } else {
+ return DevicePlcVO.OperationResult.builder()
+ .success(false)
+ .message(String.format("杞﹁締 %s (%s) 褰撳墠鐘舵�佷负 %s锛屾棤娉曟墽琛屾搷浣� %s",
+ deviceConfig.getDeviceName(),
+ deviceId,
+ status.getState(),
+ operation))
+ .build();
+ }
}
}
@@ -187,6 +211,15 @@
case "stopTaskMonitor":
result = handleStopTaskMonitor(deviceConfig);
break;
+ case "setOnlineState":
+ result = handleSetOnlineState(deviceConfig, params, logicParams);
+ break;
+ case "checkMesConfirm":
+ result = checkMesConfirm(deviceConfig, logicParams);
+ break;
+ case "markBroken":
+ result = handleMarkBroken(deviceConfig, params, logicParams);
+ break;
default:
log.warn("涓嶆敮鎸佺殑鎿嶄綔绫诲瀷: {}", operation);
result = DevicePlcVO.OperationResult.builder()
@@ -219,8 +252,14 @@
* 鍒ゆ柇鎿嶄綔鏄惁闇�瑕佺姸鎬佹鏌�
*/
private boolean needsStateCheck(String operation) {
- // 鎵�鏈夋搷浣滈兘闇�瑕佹鏌ョ姸鎬侊紝闄や簡鏌ヨ绫绘搷浣�
- return !"query".equals(operation) && !"status".equals(operation);
+ // 鎵�鏈夋搷浣滈兘闇�瑕佹鏌ョ姸鎬侊紝闄や簡鏌ヨ绫绘搷浣滃拰鐗瑰畾鍐呴儴妫�鏌�
+ if ("query".equals(operation) || "status".equals(operation)) {
+ return false;
+ }
+ if ("checkMesConfirm".equals(operation)) {
+ return false;
+ }
+ return true;
}
/**
@@ -256,7 +295,23 @@
}
// 浠庨厤缃腑鑾峰彇閫熷害锛堝鏋滄湁锛�
- Double speed = getLogicParam(logicParams, "vehicleSpeed", null);
+ Object speedObj = logicParams != null ? logicParams.get("vehicleSpeed") : null;
+ Double speed = null;
+ if (speedObj != null) {
+ if (speedObj instanceof Double) {
+ speed = (Double) speedObj;
+ } else if (speedObj instanceof Integer) {
+ speed = ((Integer) speedObj).doubleValue();
+ } else if (speedObj instanceof Number) {
+ speed = ((Number) speedObj).doubleValue();
+ } else {
+ try {
+ speed = Double.parseDouble(String.valueOf(speedObj));
+ } catch (NumberFormatException e) {
+ log.warn("鏃犳硶瑙f瀽vehicleSpeed: {}", speedObj);
+ }
+ }
+ }
if (speed != null) {
task.setSpeed(speed);
task.calculateEstimatedEndTime();
@@ -284,9 +339,8 @@
// 浠庨�昏緫鍙傛暟涓幏鍙栭厤缃紙浠� extraParams.deviceLogic 璇诲彇锛�
Integer vehicleCapacity = getLogicParam(logicParams, "vehicleCapacity", 6000);
- Integer glassIntervalMs = getLogicParam(logicParams, "glassIntervalMs", 1000);
- Boolean autoFeed = getLogicParam(logicParams, "autoFeed", true);
- Integer maxRetryCount = getLogicParam(logicParams, "maxRetryCount", 5);
+ Integer glassGap = getLogicParam(logicParams, "glassGap", 200); // 鐜荤拑涔嬮棿鐨勭墿鐞嗛棿闅旓紙mm锛夛紝榛樿200mm
+ Boolean autoFeed = getLogicParam(logicParams, "autoFeed", true); // 鑷姩涓婃枡锛氭槸鍚﹁嚜鍔ㄨЕ鍙戜笂鏂欒姹傦紙鍐欏叆plcRequest=1锛�
// 浠庤繍琛屾椂鍙傛暟涓幏鍙栨暟鎹紙浠庢帴鍙h皟鐢ㄦ椂浼犲叆锛�
List<GlassInfo> glassInfos = extractGlassInfos(params);
@@ -301,7 +355,7 @@
Integer positionValue = (Integer) params.get("positionValue");
Boolean triggerRequest = (Boolean) params.getOrDefault("triggerRequest", autoFeed);
- List<GlassInfo> plannedGlasses = planGlassLoading(glassInfos, vehicleCapacity,
+ List<GlassInfo> plannedGlasses = planGlassLoading(glassInfos, vehicleCapacity, glassGap,
deviceConfig.getDeviceId());
if (plannedGlasses == null) {
// 鐜荤拑娌℃湁闀垮害鏃惰繑鍥瀗ull琛ㄧず閿欒
@@ -311,11 +365,20 @@
.build();
}
if (plannedGlasses.isEmpty()) {
+ // 瑁呬笉涓嬶紝閫氱煡鍗ц浆绔嬫壂鐮佽澶囨殏鍋�
+ notifyScannerPause(params, true);
+ log.warn("澶ц溅璁惧瑁呬笉涓嬶紝宸查�氱煡鍗ц浆绔嬫壂鐮佹殏鍋�: deviceId={}, glassCount={}, vehicleCapacity={}",
+ deviceConfig.getId(), glassInfos.size(), vehicleCapacity);
return DevicePlcVO.OperationResult.builder()
.success(false)
- .message("褰撳墠鐜荤拑灏哄瓒呭嚭杞﹁締瀹归噺锛屾棤娉曡杞�")
+ .message("褰撳墠鐜荤拑灏哄瓒呭嚭杞﹁締瀹归噺锛屾棤娉曡杞斤紝宸查�氱煡鍗ц浆绔嬫壂鐮佹殏鍋�")
.build();
}
+
+ // 瑁呭緱涓嬶紝纭繚鍗ц浆绔嬫壂鐮佺户缁繍琛�
+ notifyScannerPause(params, false);
+
+ // 缁х画鎵ц鍘熸湁閫昏緫
// 鏋勫缓鍐欏叆鏁版嵁
Map<String, Object> payload = new HashMap<>();
@@ -328,17 +391,21 @@
}
payload.put("plcGlassCount", plcSlots);
- // 鍐欏叆浣嶇疆淇℃伅
+ // 鍐欏叆浣嶇疆淇℃伅锛歅LC渚ф湡鏈涚殑鏄� MES 缂栧彿锛堝1001/1002锛夛紝鑰屼笉鏄綅缃槧灏勫悗鐨勬牸瀛愬��
+ Integer plcPosition = null;
if (positionValue != null) {
- payload.put("inPosition", positionValue);
+ // 濡傛灉璋冪敤鏂圭洿鎺ヤ紶浜嗘暟鍊硷紝鍒欒涓鸿繖鏄疢ES缂栧彿锛岀洿鎺ュ啓鍏�
+ plcPosition = positionValue;
} else if (positionCode != null) {
- // 浠庝綅缃槧灏勪腑鑾峰彇浣嶇疆鍊�
- @SuppressWarnings("unchecked")
- Map<String, Integer> positionMapping = getLogicParam(logicParams, "positionMapping", new HashMap<>());
- Integer mappedValue = positionMapping.get(positionCode);
- if (mappedValue != null) {
- payload.put("inPosition", mappedValue);
+ // 灏濊瘯灏嗕綅缃唬鐮佽В鏋愪负鏁板瓧锛堜緥濡� "900" -> 900锛�
+ try {
+ plcPosition = Integer.parseInt(positionCode.trim());
+ } catch (NumberFormatException ignore) {
+ // 闈炴暟瀛楃紪鐮佹椂锛屼笉鍐欏叆inPosition锛岀敱PLC鎴栧悗缁�昏緫鑷澶勭悊
}
+ }
+ if (plcPosition != null) {
+ payload.put("inPosition", plcPosition);
}
// 鑷姩瑙﹀彂璇锋眰瀛�
@@ -354,18 +421,11 @@
log.info("澶ц溅璁惧鐜荤拑涓婃枡: deviceId={}, glassCount={}, position={}, plannedGlassIds={}",
deviceConfig.getId(), plcSlots, positionCode, plannedGlasses);
- if (glassIntervalMs != null && glassIntervalMs > 0) {
- try {
- Thread.sleep(glassIntervalMs);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
-
+ // 鍐欏叆PLC锛岃澶ц溅寮�濮嬭鐜荤拑
DevicePlcVO.OperationResult result = devicePlcOperationService.writeFields(
deviceConfig.getId(), payload, operationName);
- // 濡傛灉鎵ц鎴愬姛锛屾洿鏂颁綅缃俊鎭埌鐘舵�侊紝骞跺惎鍔ㄧ姸鎬佺洃鎺�
+ // 濡傛灉鎵ц鎴愬姛锛屾洿鏂颁綅缃俊鎭埌鐘舵��
if (Boolean.TRUE.equals(result.getSuccess())) {
VehicleStatus status = statusManager.getOrCreateVehicleStatus(
deviceConfig.getDeviceId(), deviceConfig.getDeviceName());
@@ -373,9 +433,16 @@
VehiclePosition position = new VehiclePosition(positionCode, positionValue);
status.setCurrentPosition(position);
}
-
- // 鍚姩鑷姩鐘舵�佺洃鎺э紝褰� state=1 鏃惰嚜鍔ㄥ崗璋冨崸杞珛璁惧
- startStateMonitoring(deviceConfig, logicParams);
+
+ // 浠呭湪鈥滈潪澶氳澶囦换鍔♀�濆満鏅笅锛屾墠鍚姩澶ц溅鑷韩鐨勮嚜鍔ㄧ姸鎬佺洃鎺у拰 MES 浠诲姟鐩戞帶
+ boolean inMultiDeviceTask = params != null && params.containsKey("_taskContext");
+ if (!inMultiDeviceTask) {
+ // 鍚姩鑷姩鐘舵�佺洃鎺э紝褰� state=1 鏃惰嚜鍔ㄥ崗璋冨崸杞珛璁惧
+ startStateMonitoring(deviceConfig, logicParams);
+
+ // 浠� PLC/MES 鍒涘缓姝e紡浠诲姟骞跺惎鍔ㄧ洃鎺х殑閫昏緫锛屼繚鐣欑粰鐙珛 MES 鍦烘櫙浣跨敤
+ // 澶氳澶囦换鍔″満鏅笅锛岃繖閮ㄥ垎浜ょ敱 TaskExecutionEngine 缁熶竴缂栨帓
+ }
}
return result;
@@ -430,6 +497,11 @@
Map<String, Object> payload = new HashMap<>();
payload.put("plcRequest", 0);
payload.put("plcReport", 0);
+ // 娓呯┖state1~6锛岄伩鍏嶉仐鐣欑姸鎬佸鑷磋鍒�
+ for (int i = 1; i <= 6; i++) {
+ payload.put("state" + i, 0);
+ }
+ payload.put("onlineState", Boolean.TRUE);
log.info("澶ц溅璁惧閲嶇疆: deviceId={}", deviceConfig.getId());
@@ -444,8 +516,72 @@
statusManager.clearVehicleTask(deviceConfig.getDeviceId());
statusManager.updateVehicleStatus(deviceConfig.getDeviceId(), VehicleState.IDLE);
stopStateMonitoring(deviceConfig.getDeviceId());
+ handleStopTaskMonitor(deviceConfig);
+ handleStopIdleMonitor(deviceConfig);
+ updateDeviceOnlineStatus(deviceConfig, true);
+ } else {
+ // 鍗充究閲嶇疆澶辫触锛屼篃灏濊瘯鍋滄鍐呴儴鐩戞帶锛岄伩鍏嶄换鍔″彇娑堝悗浠嶇劧鍙嶅鍐橮LC
+ stopStateMonitoring(deviceConfig.getDeviceId());
+ handleStopTaskMonitor(deviceConfig);
+ handleStopIdleMonitor(deviceConfig);
}
+ return result;
+ }
+
+ /**
+ * 璁剧疆鑱旀満鐘舵��
+ * @param deviceConfig 璁惧閰嶇疆
+ * @param params 鍙傛暟锛屽彲鍖呭惈 onlineState锛�1=鑱旀満锛�0=鑴辨満锛�
+ * @param logicParams 閫昏緫鍙傛暟
+ * @return 鎿嶄綔缁撴灉
+ */
+ private DevicePlcVO.OperationResult handleSetOnlineState(
+ DeviceConfig deviceConfig,
+ Map<String, Object> params,
+ Map<String, Object> logicParams) {
+
+ // 浠庡弬鏁颁腑鑾峰彇鑱旀満鐘舵�佸�硷紝榛樿涓簍rue锛堣仈鏈猴級
+ boolean onlineState = true;
+ if (params != null && params.containsKey("onlineState")) {
+ Object stateObj = params.get("onlineState");
+ if (stateObj instanceof Boolean) {
+ onlineState = (Boolean) stateObj;
+ } else if (stateObj instanceof Number) {
+ onlineState = ((Number) stateObj).intValue() != 0;
+ } else if (stateObj instanceof String) {
+ try {
+ String str = ((String) stateObj).trim();
+ if ("true".equalsIgnoreCase(str)) {
+ onlineState = true;
+ } else if ("false".equalsIgnoreCase(str)) {
+ onlineState = false;
+ } else {
+ onlineState = Integer.parseInt(str) != 0;
+ }
+ } catch (NumberFormatException e) {
+ log.warn("瑙f瀽onlineState澶辫触锛屼娇鐢ㄩ粯璁ゅ�紅rue: deviceId={}, value={}",
+ deviceConfig.getId(), stateObj);
+ }
+ }
+ }
+
+ Map<String, Object> payload = new HashMap<>();
+ payload.put("onlineState", onlineState);
+
+ String stateText = onlineState ? "鑱旀満" : "鑴辨満";
+ log.info("澶ц溅璁惧璁剧疆鑱旀満鐘舵��: deviceId={}, onlineState={} ({})",
+ deviceConfig.getId(), onlineState, stateText);
+
+ DevicePlcVO.OperationResult result = devicePlcOperationService.writeFields(
+ deviceConfig.getId(),
+ payload,
+ "澶ц溅璁惧-璁剧疆鑱旀満鐘舵��(" + stateText + ")"
+ );
+
+ if (Boolean.TRUE.equals(result.getSuccess())) {
+ updateDeviceOnlineStatus(deviceConfig, onlineState);
+ }
return result;
}
@@ -469,9 +605,9 @@
payload.put(field, "");
}
- payload.put("plcGlassCount", 0);
payload.put("plcRequest", 0);
payload.put("plcReport", 0);
+ payload.put("onlineState", Boolean.TRUE);
if (params != null && params.containsKey("positionValue")) {
payload.put("inPosition", params.get("positionValue"));
@@ -486,15 +622,39 @@
payload,
"澶ц溅璁惧-娓呯┖鐜荤拑鏁版嵁"
);
+
+ // 鍚屾娓呯┖state1~6绛夊姩鎬佸瓧娈碉紙鍦ㄥ姩鎬佹暟鎹尯涓級
+ clearDynamicTaskStates(deviceConfig);
// 娓呯┖鍚庯紝鎭㈠涓虹┖闂茬姸鎬侊紝鍋滄鐩戞帶
if (Boolean.TRUE.equals(result.getSuccess())) {
statusManager.clearVehicleTask(deviceConfig.getDeviceId());
statusManager.updateVehicleStatus(deviceConfig.getDeviceId(), VehicleState.IDLE);
stopStateMonitoring(deviceConfig.getDeviceId());
+ handleStopTaskMonitor(deviceConfig);
+ handleStopIdleMonitor(deviceConfig);
+ updateDeviceOnlineStatus(deviceConfig, true);
+ } else {
+ // 鍐欏叆澶辫触涔熷皾璇曞仠姝㈢洃鎺э紝閬垮厤浠诲姟鍙栨秷鍚庝粛鏃ц繍琛�
+ stopStateMonitoring(deviceConfig.getDeviceId());
+ handleStopTaskMonitor(deviceConfig);
+ handleStopIdleMonitor(deviceConfig);
}
return result;
+ }
+
+ private void updateDeviceOnlineStatus(DeviceConfig deviceConfig, boolean online) {
+ if (deviceStatusService == null || deviceConfig == null || deviceConfig.getId() == null) {
+ return;
+ }
+ try {
+ String status = online ? DeviceStatus.Status.ONLINE : DeviceStatus.Status.OFFLINE;
+ deviceStatusService.updateDeviceOnlineStatus(deviceConfig.getId(), status);
+ } catch (Exception e) {
+ log.warn("鍚屾璁惧鍦ㄧ嚎鐘舵�佸埌鏁版嵁搴撳け璐�: deviceId={}, online={}, error={}",
+ deviceConfig.getDeviceId(), online, e.getMessage());
+ }
}
private List<String> resolveGlassSlotFields(Map<String, Object> logicParams, int fallbackCount) {
@@ -532,9 +692,9 @@
return "杞﹁締瀹归噺(vehicleCapacity)蹇呴』澶т簬0";
}
- Integer glassIntervalMs = getLogicParam(logicParams, "glassIntervalMs", null);
- if (glassIntervalMs != null && glassIntervalMs < 0) {
- return "鐜荤拑闂撮殧鏃堕棿(glassIntervalMs)涓嶈兘涓鸿礋鏁�";
+ Integer glassGap = getLogicParam(logicParams, "glassGap", null);
+ if (glassGap != null && glassGap < 0) {
+ return "鐜荤拑闂撮殧(glassGap)涓嶈兘涓鸿礋鏁�";
}
return null; // 楠岃瘉閫氳繃
@@ -544,10 +704,9 @@
public String getDefaultLogicParams() {
Map<String, Object> defaultParams = new HashMap<>();
defaultParams.put("vehicleCapacity", 6000);
- defaultParams.put("glassIntervalMs", 1000);
- defaultParams.put("autoFeed", true);
+ defaultParams.put("glassGap", 200); // 鐜荤拑涔嬮棿鐨勭墿鐞嗛棿闅旓紙mm锛夛紝榛樿200mm
+ defaultParams.put("autoFeed", true); // 鑷姩涓婃枡锛氭槸鍚﹁嚜鍔ㄨЕ鍙戜笂鏂欒姹傦紙鍐欏叆plcRequest=1锛夛紝榛樿true
defaultParams.put("maxRetryCount", 5);
- defaultParams.put("defaultGlassLength", 2000);
// MES浠诲姟鐩稿叧閰嶇疆
defaultParams.put("vehicleSpeed", 1.0); // 杞﹁締閫熷害锛堟牸/绉掞紝grid/s锛夛紝榛樿1鏍�/绉�
@@ -647,22 +806,25 @@
/**
* 瑙勫垝鐜荤拑瑁呰浇
* @param source 婧愮幓鐠冨垪琛�
- * @param vehicleCapacity 杞﹁締瀹归噺
+ * @param vehicleCapacity 杞﹁締瀹归噺锛坢m锛�
+ * @param glassGap 鐜荤拑涔嬮棿鐨勭墿鐞嗛棿闅旓紙mm锛夛紝榛樿200mm
* @param deviceId 璁惧ID锛堢敤浜庢棩蹇楋級
- * @return 瑙勫垝鍚庣殑鐜荤拑鍒楄〃锛屽鏋滅幓鐠冩病鏈夐暱搴﹀垯杩斿洖null锛堢敤浜庢祴璇昅ES绋嬪簭锛�
+ * @return 瑙勫垝鍚庣殑鐜荤拑鍒楄〃锛屽鏋滅幓鐠冩病鏈夐暱搴﹀垯杩斿洖null锛圡ES鏈彁渚涢暱搴︽暟鎹級
*/
private List<GlassInfo> planGlassLoading(List<GlassInfo> source,
int vehicleCapacity,
+ int glassGap,
String deviceId) {
List<GlassInfo> planned = new ArrayList<>();
int usedLength = 0;
int capacity = Math.max(vehicleCapacity, 1);
+ int gap = Math.max(glassGap, 0); // 纭繚闂撮殧涓嶄负璐熸暟
for (GlassInfo info : source) {
Integer glassLength = info.getLength();
+ // 濡傛灉鐜荤拑娌℃湁闀垮害锛岃鏄嶮ES鏈彁渚涳紝鐩存帴鎶ラ敊
if (glassLength == null || glassLength <= 0) {
- // 鐜荤拑娌℃湁闀垮害锛岀洿鎺ユ姤閿欙紙鐢ㄤ簬娴嬭瘯MES绋嬪簭锛�
log.error("鐜荤拑[{}]缂哄皯闀垮害鏁版嵁锛屾棤娉曡繘琛屽閲忚绠椼�俤eviceId={}锛岃妫�鏌ES绋嬪簭鏄惁姝g‘鎻愪緵鐜荤拑闀垮害銆�",
info.getGlassId(), deviceId);
return null;
@@ -671,17 +833,26 @@
int length = glassLength;
if (planned.isEmpty()) {
+ // 绗竴鍧楃幓鐠冿紝涓嶉渶瑕侀棿闅�
planned.add(info.withLength(length));
usedLength = length;
continue;
}
- if (usedLength + length <= capacity) {
+
+ // 鍚庣画鐜荤拑闇�瑕佽�冭檻闂撮殭锛氱幓鐠冮暱搴� + 闂撮殭
+ int requiredLength = length + gap;
+ if (usedLength + requiredLength <= capacity) {
planned.add(info.withLength(length));
- usedLength += length;
+ usedLength += requiredLength; // 鍖呭惈闂撮殭
} else {
+ // 瑁呬笉涓嬩簡锛屽仠姝㈡坊鍔�
break;
}
}
+
+ log.debug("鐜荤拑瑁呰浇瑙勫垝: deviceId={}, total={}, planned={}, usedLength={}, capacity={}, glassGap={}",
+ deviceId, source.size(), planned.size(), usedLength, capacity, gap);
+
return planned;
}
@@ -1148,84 +1319,157 @@
}
try {
+ // 妫�鏌ユ槸鍚﹀凡鏈変换鍔″湪鎵ц涓�
+ MesTaskInfo existingTask = currentTasks.get(deviceId);
+ if (existingTask != null) {
+ log.debug("璁惧宸叉湁浠诲姟鍦ㄦ墽琛屼腑锛岃烦杩囨鏌ES浠诲姟: deviceId={}", deviceId);
+ return DevicePlcVO.OperationResult.builder()
+ .success(true)
+ .message("浠诲姟鎵ц涓紝鏃犻渶閲嶅妫�鏌ES浠诲姟")
+ .data(Collections.singletonMap("waiting", false))
+ .build();
+ }
+
// 璇诲彇MES瀛楁锛堣繘鐗囧拰鍑虹墖鍏辩敤锛�
Map<String, Object> mesData = plcDynamicDataService.readPlcData(
deviceConfig, MES_FIELDS, serializer);
if (mesData == null || mesData.isEmpty()) {
+ log.warn("璇诲彇MES瀛楁澶辫触: deviceId={}, mesData涓虹┖鎴杗ull", deviceId);
return DevicePlcVO.OperationResult.builder()
.success(false)
.message("璇诲彇MES瀛楁澶辫触")
.build();
}
-
+
+ // 瑙f瀽mesSend
Integer mesSend = parseInteger(mesData.get("mesSend"));
+
if (mesSend == null || mesSend == 0) {
+ Map<String, Object> waitData = new HashMap<>();
+ waitData.put("completed", false);
+ waitData.put("waiting", true);
+ waitData.put("waitingReason", "mesSend=0");
return DevicePlcVO.OperationResult.builder()
.success(true)
- .message("鏆傛棤MES浠诲姟锛坢esSend=0锛�")
+ .message("绛夊緟MES鍙戦�佽姹傦紙mesSend=0锛�")
+ .data(waitData)
.build();
}
- // mesSend=1锛岃鍙栦换鍔″弬鏁�
- String glassId = parseString(mesData.get("mesGlassId"));
- Integer startSlot = parseInteger(mesData.get("startSlot")); // 璧峰浣嶇疆缂栧彿
- Integer targetSlot = parseInteger(mesData.get("targetSlot")); // 鐩爣浣嶇疆缂栧彿
- Integer workLine = parseInteger(mesData.get("workLine"));
+ // mesSend=1锛岃褰曟棩蹇�
+ log.info("妫�娴嬪埌mesSend=1锛屽紑濮嬭鍙朚ES浠诲姟淇℃伅: deviceId={}", deviceId);
- if (glassId == null || glassId.isEmpty()) {
- return DevicePlcVO.OperationResult.builder()
- .success(false)
- .message("MES鏈彁渚涚幓鐠僆D")
- .build();
+ // mesSend=1锛岃鍙栨墍鏈夌幓鐠冪殑浠诲姟鍙傛暟锛堟敮鎸�1-6涓幓鐠冿級
+ List<GlassTaskInfo> glasses = new ArrayList<>();
+ boolean isOutbound = false; // 灏嗗湪澶勭悊绗竴涓湁鏁堢幓鐠冩椂纭畾
+
+ // 璇诲彇鎵�鏈�6涓幓鐠冪殑淇℃伅
+ for (int i = 1; i <= 6; i++) {
+ String glassId = parseString(mesData.get("mesGlassId" + i));
+ if (glassId == null || glassId.isEmpty()) {
+ continue; // 璺宠繃绌虹殑鐜荤拑ID
+ }
+
+ Integer startSlot = parseInteger(mesData.get("start" + i));
+ Integer targetSlot = parseInteger(mesData.get("target" + i));
+ Integer width = parseInteger(mesData.get("mesWidth" + i));
+ Integer height = parseInteger(mesData.get("mesHeight" + i));
+ Integer thickness = parseInteger(mesData.get("mesThickness" + i));
+
+ log.debug("璇诲彇鐜荤拑{}淇℃伅: deviceId={}, glassId={}, startSlot={}, targetSlot={}, width={}, height={}, thickness={}",
+ i, deviceId, glassId, startSlot, targetSlot, width, height, thickness);
+
+ if (startSlot == null || targetSlot == null) {
+ log.warn("鐜荤拑{}淇℃伅涓嶅畬鏁达紝璺宠繃: glassId={}, startSlot={}, targetSlot={}",
+ i, glassId, startSlot, targetSlot);
+ continue;
+ }
+
+ // 瀵逛簬绗竴涓湁鏁堢幓鐠冿紝鍒ゆ柇鏄繘鐗囪繕鏄嚭鐗囦换鍔�
+ if (glasses.isEmpty()) {
+ isOutbound = isOutboundTask(startSlot, logicParams);
+ }
+
+ // 浣嶇疆鏄犲皠
+ Integer startPosition;
+ if (isOutbound) {
+ // 鍑虹墖浠诲姟锛歴tartSlot鏄牸瀛愮紪鍙凤紝闇�瑕佹槧灏勫埌瀹為檯浣嶇疆
+ startPosition = mapOutboundPosition(startSlot, logicParams);
+ } else {
+ // 杩涚墖浠诲姟锛歴tartSlot鏄崸杞珛缂栧彿锛岄�氳繃positionMapping鏄犲皠
+ startPosition = mapPosition(startSlot, logicParams);
+ }
+
+ // targetSlot缁熶竴閫氳繃positionMapping鏄犲皠
+ Integer targetPosition = mapPosition(targetSlot, logicParams);
+
+ if (startPosition == null || targetPosition == null) {
+ log.warn("鐜荤拑{}浣嶇疆鏄犲皠澶辫触锛岃烦杩�: glassId={}, startSlot={}, targetSlot={}",
+ i, glassId, startSlot, targetSlot);
+ continue;
+ }
+
+ // 鍒涘缓鐜荤拑浠诲姟淇℃伅
+ GlassTaskInfo glassInfo = new GlassTaskInfo();
+ glassInfo.glassId = glassId;
+ glassInfo.startSlot = startSlot;
+ glassInfo.targetSlot = targetSlot;
+ glassInfo.startPosition = startPosition;
+ glassInfo.targetPosition = targetPosition;
+ glassInfo.width = width;
+ glassInfo.height = height;
+ glassInfo.thickness = thickness;
+ glasses.add(glassInfo);
}
- // 鍒ゆ柇鏄繘鐗囪繕鏄嚭鐗囦换鍔�
- // 鏂规硶锛氶�氳繃startSlot鍒ゆ柇
- // - 濡傛灉startSlot鏄崸杞珛缂栧彿锛堝900/901锛夛紝鍒欐槸杩涚墖浠诲姟
- // - 濡傛灉startSlot鏄牸瀛愮紪鍙凤紙鍦ㄥぇ鐞嗙墖绗艰寖鍥村唴锛夛紝鍒欐槸鍑虹墖浠诲姟
- boolean isOutbound = isOutboundTask(startSlot, logicParams);
-
- // 浣嶇疆鏄犲皠
- Integer startPosition;
- if (isOutbound) {
- // 鍑虹墖浠诲姟锛歴tartSlot鏄牸瀛愮紪鍙凤紝闇�瑕佹槧灏勫埌瀹為檯浣嶇疆
- startPosition = mapOutboundPosition(startSlot, logicParams);
- } else {
- // 杩涚墖浠诲姟锛歴tartSlot鏄崸杞珛缂栧彿锛岄�氳繃positionMapping鏄犲皠
- startPosition = mapPosition(startSlot, logicParams);
- }
-
- // targetSlot缁熶竴閫氳繃positionMapping鏄犲皠
- Integer targetPosition = mapPosition(targetSlot, logicParams);
-
- if (startPosition == null || targetPosition == null) {
+ if (glasses.isEmpty()) {
+ // 璁板綍璇︾粏鐨凪ES鏁版嵁锛屽府鍔╄皟璇�
+ log.warn("MES鏈彁渚涙湁鏁堢殑鐜荤拑淇℃伅: deviceId={}, mesSend={}, mesData={}",
+ deviceId, mesSend, mesData);
+ Map<String, Object> waitData = new HashMap<>();
+ waitData.put("completed", false);
+ waitData.put("waiting", true);
+ waitData.put("waitingReason", "glassInfoMissing");
return DevicePlcVO.OperationResult.builder()
.success(false)
- .message(String.format("浣嶇疆鏄犲皠澶辫触: startSlot=%s, targetSlot=%s, isOutbound=%s",
- startSlot, targetSlot, isOutbound))
+ .message("MES鏈彁渚涙湁鏁堢殑鐜荤拑淇℃伅锛坢esSend=1浣嗘湭鎵惧埌鏈夋晥鐨刧lassId銆乻tartSlot銆乼argetSlot锛�")
+ .data(waitData)
.build();
}
// 璇诲彇褰撳墠浣嶇疆
Integer currentPosition = getCurrentPosition(deviceConfig, logicParams);
- // 璁$畻鏃堕棿
+ // 浣跨敤绗竴涓幓鐠冪殑浣嶇疆璁$畻鏃堕棿锛堟墍鏈夌幓鐠冧娇鐢ㄧ浉鍚岀殑璺緞锛�
+ GlassTaskInfo firstGlass = glasses.get(0);
TimeCalculation timeCalc = calculateTime(
- currentPosition, startPosition, targetPosition, logicParams);
+ currentPosition, firstGlass.startPosition, firstGlass.targetPosition, logicParams);
// 鍒涘缓浠诲姟淇℃伅
MesTaskInfo taskInfo = new MesTaskInfo();
- taskInfo.glassId = glassId;
- taskInfo.startSlot = startSlot;
- taskInfo.targetSlot = targetSlot;
- taskInfo.startPosition = startPosition;
- taskInfo.targetPosition = targetPosition;
+ taskInfo.glasses = glasses;
taskInfo.currentPosition = currentPosition;
taskInfo.gotime = timeCalc.gotime;
taskInfo.cartime = timeCalc.cartime;
- taskInfo.workLine = workLine;
taskInfo.createdTime = System.currentTimeMillis();
taskInfo.isOutbound = isOutbound;
+
+ // 浠庨厤缃腑璇诲彇鐮存崯鐜荤拑绱㈠紩锛堢敤浜庢祴璇曞満鏅級
+ // 閰嶇疆鏍煎紡锛歜rokenGlassIndices: [0, 2] 琛ㄧず绗�1涓拰绗�3涓幓鐠冨簲璇ョ牬鎹�
+ @SuppressWarnings("unchecked")
+ List<Integer> brokenIndices = getLogicParam(logicParams, "brokenGlassIndices", null);
+ if (brokenIndices != null && !brokenIndices.isEmpty()) {
+ taskInfo.brokenGlassIndices = new ArrayList<>();
+ for (Integer index : brokenIndices) {
+ if (index != null && index >= 0 && index < glasses.size()) {
+ taskInfo.brokenGlassIndices.add(index);
+ }
+ }
+ if (!taskInfo.brokenGlassIndices.isEmpty()) {
+ log.info("浠诲姟鍒涘缓鏃舵爣璁扮牬鎹熺幓鐠�: deviceId={}, brokenIndices={}",
+ deviceId, taskInfo.brokenGlassIndices);
+ }
+ }
currentTasks.put(deviceId, taskInfo);
@@ -1233,23 +1477,43 @@
Map<String, Object> payload = new HashMap<>();
payload.put("plcRequest", 0);
plcDynamicDataService.writePlcData(deviceConfig, payload, serializer);
+ log.info("宸叉竻绌簆lcRequest=0: deviceId={}", deviceId);
// 鏇存柊杞﹁締鐘舵�佷负鎵ц涓�
statusManager.updateVehicleStatus(deviceId, deviceConfig.getDeviceName(), VehicleState.EXECUTING);
// 鍚姩浠诲姟鐩戞帶
handleStartTaskMonitor(deviceConfig, params, logicParams);
+ log.info("宸插惎鍔ㄤ换鍔$洃鎺�: deviceId={}", deviceId);
String taskType = isOutbound ? "鍑虹墖" : "杩涚墖";
- log.info("MES{}浠诲姟宸插垱寤�: deviceId={}, glassId={}, startSlot={}(浣嶇疆{}鏍�), targetSlot={}(浣嶇疆{}鏍�), 璺濈{}鏍�->{}鏍�, gotime={}ms({}绉�), cartime={}ms({}绉�)",
- taskType, deviceId, glassId, startSlot, startPosition, targetSlot, targetPosition,
- Math.abs(startPosition - currentPosition), Math.abs(targetPosition - startPosition),
+ String glassIds = glasses.stream()
+ .map(g -> g.glassId)
+ .collect(java.util.stream.Collectors.joining(","));
+ log.info("MES{}浠诲姟宸插垱寤�: deviceId={}, glassCount={}, glassIds=[{}], 璧峰浣嶇疆={}鏍�, 鐩爣浣嶇疆={}鏍�, 璺濈{}鏍�->{}鏍�, gotime={}ms({}绉�), cartime={}ms({}绉�)",
+ taskType, deviceId, glasses.size(), glassIds,
+ firstGlass.startPosition, firstGlass.targetPosition,
+ Math.abs(firstGlass.startPosition - currentPosition),
+ Math.abs(firstGlass.targetPosition - firstGlass.startPosition),
timeCalc.gotime, timeCalc.gotime / 1000.0, timeCalc.cartime, timeCalc.cartime / 1000.0);
+
+ // 鏋勫缓璇︾粏鐨勬楠ゆ彁绀轰俊鎭�
+ StringBuilder stepMessage = new StringBuilder();
+ stepMessage.append("妫�娴嬪埌MES浠诲姟锛坢esSend=1锛夛紝宸叉竻绌鸿姹傚瓧锛坧lcRequest=0锛�");
+ stepMessage.append("锛涘紑濮嬭绠楁椂闂达紝棰勮鍒拌揪璧峰浣嶇疆鑰楁椂").append(timeCalc.gotime / 1000.0).append("绉�");
+ stepMessage.append("锛岃繍杈撳埌鐩爣浣嶇疆鑰楁椂").append(timeCalc.cartime / 1000.0).append("绉�");
+ if (!isOutbound) {
+ stepMessage.append("锛涜繘鐗囦换鍔★細绛夊緟鐜荤拑涓婅溅鍚庯紝灏嗗憡鐭ュ崸杞珛璁惧");
+ }
+
+ Map<String, Object> successData = new HashMap<>();
+ successData.put("waiting", false);
+ successData.put("taskStarted", true);
return DevicePlcVO.OperationResult.builder()
.success(true)
- .message(String.format("MES%s浠诲姟宸插垱寤�: glassId=%s, start=%d, target=%d",
- taskType, glassId, startPosition, targetPosition))
+ .message(stepMessage.toString())
+ .data(successData)
.build();
} catch (Exception e) {
@@ -1401,7 +1665,22 @@
}
// 鑾峰彇閫熷害锛堟牸/绉掞紝grid/s锛�
- Double speed = getLogicParam(logicParams, "vehicleSpeed", 1.0);
+ // 杩欓噷涓嶈兘鐩存帴鐢� Double 娉涘瀷锛屽惁鍒欏綋閰嶇疆閲屾槸 Integer 鏃朵細鍑虹幇
+ // java.lang.Integer cannot be cast to java.lang.Double 鐨勫紓甯�
+ Object speedObj = getLogicParam(logicParams, "vehicleSpeed", 1.0);
+ Double speed = null;
+ if (speedObj instanceof Double) {
+ speed = (Double) speedObj;
+ } else if (speedObj instanceof Integer) {
+ speed = ((Integer) speedObj).doubleValue();
+ } else if (speedObj instanceof Number) {
+ speed = ((Number) speedObj).doubleValue();
+ } else {
+ try {
+ speed = Double.parseDouble(String.valueOf(speedObj));
+ } catch (Exception ignore) {
+ }
+ }
if (speed == null || speed <= 0) {
speed = 1.0; // 榛樿1鏍�/绉�
}
@@ -1515,24 +1794,90 @@
long state1Time = taskInfo.gotime; // 鍒拌揪璧峰浣嶇疆锛屼笂杞﹀畬鎴�
long state2Time = taskInfo.gotime + taskInfo.cartime; // 鍒拌揪鐩爣浣嶇疆锛岃繍杈撳畬鎴�
- // 鏇存柊state鐘舵��
- if (elapsed >= state1Time && elapsed < state2Time) {
- // state搴旇涓�1
- if (taskInfo.isOutbound) {
- // 鍑虹墖浠诲姟锛氬埌杈炬簮浣嶇疆锛堝ぇ鐞嗙墖绗硷級锛屽彇鐗囧畬鎴�
- updateStateIfNeeded(deviceConfig, serializer, stateValues, 1, taskInfo);
- } else {
- // 杩涚墖浠诲姟锛氬埌杈捐捣濮嬩綅缃紙鍗ц浆绔嬶級锛屼笂杞﹀畬鎴�
- updateStateIfNeeded(deviceConfig, serializer, stateValues, 1, taskInfo);
- }
- } else if (elapsed >= state2Time) {
- // state搴旇涓�2锛堣繍杈撳畬鎴愶級
- updateStateIfNeeded(deviceConfig, serializer, stateValues, 2, taskInfo);
+ // 鑾峰彇瓒呮椂鏃堕棿閰嶇疆锛堥粯璁わ細瓒呰繃棰勬湡瀹屾垚鏃堕棿鐨�200%瑙嗕负瓒呮椂鏈畬鎴愶級
+ Double timeoutRatio = getLogicParam(logicParams, "state3TimeoutRatio", 2.0);
+ long state3TimeoutTime = (long) (state2Time * timeoutRatio); // 瓒呮椂鏃堕棿鐐�
+
+ // 鏇存柊state鐘舵�侊紙姣忎釜鐜荤拑瀵瑰簲涓�涓猻tate锛�
+ int glassCount = taskInfo.glasses.size();
+ boolean hasStateOne = false; // 鏍囪鏄惁鏈塻tate鍙樹负1
+ boolean hasStateTwo = false; // 鏍囪鏄惁鏈塻tate鍙樹负2
+ String currentStepDesc = ""; // 褰撳墠姝ラ鎻忚堪
+
+ for (int i = 0; i < glassCount && i < 6; i++) {
+ String stateField = "state" + (i + 1);
+ Object currentValue = stateValues.get(stateField);
+ Integer currentState = parseInteger(currentValue);
- // 妫�鏌ユ槸鍚︽墍鏈塻tate閮�>=2锛屽鏋滄槸鍒欑粰MES姹囨姤
- if (allStatesCompleted(stateValues)) {
- reportToMes(deviceConfig, serializer, taskInfo, logicParams);
+ // 濡傛灉褰撳墠state宸茬粡鏄�3锛堟湭瀹屾垚锛夋垨8锛堢牬鎹燂級锛岃烦杩�
+ if (currentState != null && (currentState == 3 || currentState == 8)) {
+ continue;
}
+
+ // 浼樺厛妫�鏌ユ槸鍚︽爣璁颁负鐮存崯锛坰tate=8锛�
+ // 妫�鏌ヤ换鍔′俊鎭腑鏄惁鏍囪浜嗚鐜荤拑涓虹牬鎹�
+ if (taskInfo.brokenGlassIndices != null && taskInfo.brokenGlassIndices.contains(i)) {
+ updateStateIfNeeded(deviceConfig, serializer, stateValues, stateField, 8, taskInfo);
+ log.info("鐜荤拑鏍囪涓虹牬鎹�: deviceId={}, stateField={}, glassIndex={}",
+ deviceConfig.getDeviceId(), stateField, i);
+ continue;
+ }
+
+ // 妫�鏌ヨ秴鏃舵湭瀹屾垚锛坰tate=3锛�
+ if (elapsed >= state3TimeoutTime && (currentState == null || currentState < 2)) {
+ updateStateIfNeeded(deviceConfig, serializer, stateValues, stateField, 3, taskInfo);
+ log.warn("浠诲姟瓒呮椂鏈畬鎴�: deviceId={}, stateField={}, elapsed={}ms, expectedTime={}ms",
+ deviceConfig.getDeviceId(), stateField, elapsed, state2Time);
+ continue;
+ }
+
+ // 姝e父鐘舵�佹洿鏂�
+ if (elapsed >= state1Time && elapsed < state2Time) {
+ // state搴旇涓�1锛堜笂杞﹀畬鎴愶級
+ boolean stateChanged = updateStateIfNeeded(deviceConfig, serializer, stateValues, stateField, 1, taskInfo);
+ if (stateChanged) {
+ hasStateOne = true;
+ currentStepDesc = "鐜荤拑宸蹭笂杞︼紙state=1锛夛紝姝e湪杩愯緭鍒扮洰鏍囦綅缃�";
+ } else if (currentState != null && currentState == 1) {
+ currentStepDesc = "鐜荤拑宸蹭笂杞︼紙state=1锛夛紝姝e湪杩愯緭鍒扮洰鏍囦綅缃�";
+ }
+ } else if (elapsed >= state2Time) {
+ // state搴旇涓�2锛堣繍杈撳畬鎴愶級
+ boolean stateChanged = updateStateIfNeeded(deviceConfig, serializer, stateValues, stateField, 2, taskInfo);
+ if (stateChanged) {
+ hasStateTwo = true;
+ currentStepDesc = "鐜荤拑宸插埌杈剧洰鏍囦綅缃紙state=2锛夛紝绛夊緟MES纭";
+ } else if (currentState != null && currentState == 2) {
+ currentStepDesc = "鐜荤拑宸插埌杈剧洰鏍囦綅缃紙state=2锛夛紝绛夊緟MES纭";
+ }
+ } else {
+ // 杩樺湪鍓嶅線璧峰浣嶇疆
+ currentStepDesc = "姝e湪鍓嶅線璧峰浣嶇疆锛岄璁¤�楁椂" + (state1Time / 1000.0) + "绉�";
+ }
+ }
+
+ // 褰搒tate鍙樹负1鏃讹紙鐜荤拑涓婅溅瀹屾垚锛夛紝娓呯┖鍗ц浆绔嬭澶囩殑plcRequest锛堝彧鎵ц涓�娆★級
+ if (hasStateOne && !taskInfo.transferPlcRequestCleared) {
+ clearTransferPlcRequest(deviceConfig, logicParams);
+ taskInfo.transferPlcRequestCleared = true; // 鏍囪宸叉竻绌猴紝閬垮厤閲嶅鎵ц
+ if (!taskInfo.isOutbound) {
+ currentStepDesc = "鐜荤拑宸蹭笂杞︼紙state=1锛夛紝宸插憡鐭ュ崸杞珛璁惧锛坧lcRequest=0锛夛紝姝e湪杩愯緭鍒扮洰鏍囦綅缃�";
+ }
+ }
+
+ // 妫�鏌ユ槸鍚︽墍鏈塻tate閮�>=2锛屽鏋滄槸鍒欑粰MES姹囨姤
+ if (elapsed >= state2Time && allStatesCompleted(stateValues, glassCount)) {
+ reportToMes(deviceConfig, serializer, taskInfo, logicParams);
+ // 璁板綍MES纭寮�濮嬬瓑寰呯殑鏃堕棿锛堝彧璁板綍涓�娆★級
+ if (taskInfo.mesConfirmStartTime == null) {
+ taskInfo.mesConfirmStartTime = System.currentTimeMillis();
+ currentStepDesc = "鐜荤拑宸插埌杈剧洰鏍囦綅缃紙state=2锛夛紝宸插彂閫佹眹鎶ワ紙plcReport=1锛夛紝绛夊緟MES纭";
+ }
+ }
+
+ // 淇濆瓨褰撳墠姝ラ鎻忚堪鍒颁换鍔′俊鎭腑锛屼緵checkMesConfirm浣跨敤
+ if (!currentStepDesc.isEmpty()) {
+ taskInfo.currentStepDesc = currentStepDesc;
}
} catch (Exception e) {
@@ -1542,30 +1887,97 @@
/**
* 鏇存柊state鐘舵�侊紙濡傛灉闇�瑕侊級
+ * @return 鏄惁鍙戠敓浜嗙姸鎬佸彉鍖栵紙浠庨潪鐩爣鐘舵�佸彉涓虹洰鏍囩姸鎬侊級
*/
- private void updateStateIfNeeded(DeviceConfig deviceConfig,
+ private boolean updateStateIfNeeded(DeviceConfig deviceConfig,
EnhancedS7Serializer serializer,
Map<String, Object> currentStates,
+ String stateField,
int targetState,
MesTaskInfo taskInfo) {
- // 杩欓噷鍙互鏍规嵁瀹為檯闇�姹傛洿鏂皊tate瀛楁
- // 鏆傛椂鍙褰曟棩蹇楋紝瀹為檯鏇存柊鍙兘闇�瑕佹牴鎹叿浣揚LC瀛楁閰嶇疆
- log.debug("浠诲姟鐘舵�佹洿鏂�: deviceId={}, targetState={}",
- deviceConfig.getDeviceId(), targetState);
+ // 妫�鏌ュ綋鍓峴tate鍊�
+ Object currentValue = currentStates.get(stateField);
+ Integer currentState = parseInteger(currentValue);
+
+ // 濡傛灉褰撳墠state灏忎簬鐩爣state锛屽垯鏇存柊
+ // 娉ㄦ剰锛氬鏋滃綋鍓峴tate宸茬粡鏄�3锛堟湭瀹屾垚锛夋垨8锛堢牬鎹燂級锛屼笉鍐嶆洿鏂�
+ if (currentState != null && (currentState == 3 || currentState == 8)) {
+ log.debug("浠诲姟鐘舵�佸凡涓哄紓甯哥姸鎬侊紝涓嶅啀鏇存柊: deviceId={}, stateField={}, currentState={}, targetState={}",
+ deviceConfig.getDeviceId(), stateField, currentState, targetState);
+ return false;
+ }
+
+ if (currentState == null || currentState < targetState) {
+ // 瀹為檯鍐欏叆PLC鐨剆tate瀛楁
+ try {
+ Map<String, Object> payload = new HashMap<>();
+ payload.put(stateField, targetState);
+ plcDynamicDataService.writePlcData(deviceConfig, payload, serializer);
+
+ log.info("浠诲姟鐘舵�佸凡鏇存柊鍒癙LC: deviceId={}, stateField={}, currentState={}, targetState={}",
+ deviceConfig.getDeviceId(), stateField, currentState, targetState);
+ // 杩斿洖true琛ㄧず鐘舵�佸彂鐢熶簡鍙樺寲
+ return true;
+ } catch (Exception e) {
+ log.error("鍐欏叆PLC state瀛楁澶辫触: deviceId={}, stateField={}, targetState={}, error={}",
+ deviceConfig.getDeviceId(), stateField, targetState, e.getMessage());
+ return false;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 娓呯┖鍗ц浆绔嬭澶囩殑plcRequest锛堝綋澶ц溅state=1鏃讹紝琛ㄧず鐜荤拑宸蹭笂杞︼級
+ */
+ private void clearTransferPlcRequest(DeviceConfig deviceConfig, Map<String, Object> logicParams) {
+ try {
+ // 鏌ユ壘鍚岀粍鐨勫崸杞珛璁惧
+ List<DeviceConfig> transferDevices = findTransferDevicesInSameGroup(deviceConfig);
+ if (transferDevices.isEmpty()) {
+ log.debug("鏈壘鍒板悓缁勭殑鍗ц浆绔嬭澶囷紝璺宠繃娓呯┖plcRequest: deviceId={}", deviceConfig.getId());
+ return;
+ }
+
+ // 灏嗘瘡涓崸杞珛璁惧鐨� plcRequest 缃� 0
+ for (DeviceConfig transferDevice : transferDevices) {
+ Map<String, Object> payload = new HashMap<>();
+ payload.put("plcRequest", 0);
+
+ DevicePlcVO.OperationResult result = devicePlcOperationService.writeFields(
+ transferDevice.getId(),
+ payload,
+ "澶ц溅state=1鑷姩娓呯┖鍗ц浆绔嬭姹�"
+ );
+
+ if (Boolean.TRUE.equals(result.getSuccess())) {
+ log.info("宸茶嚜鍔ㄦ竻绌哄崸杞珛璁惧 plcRequest: vehicleDeviceId={}, transferDeviceId={}, transferDeviceName={}",
+ deviceConfig.getId(), transferDevice.getId(), transferDevice.getDeviceName());
+ } else {
+ log.warn("鑷姩娓呯┖鍗ц浆绔嬭澶� plcRequest 澶辫触: vehicleDeviceId={}, transferDeviceId={}, message={}",
+ deviceConfig.getId(), transferDevice.getId(), result.getMessage());
+ }
+ }
+ } catch (Exception e) {
+ log.error("娓呯┖鍗ц浆绔嬭澶噋lcRequest寮傚父: deviceId={}", deviceConfig.getId(), e);
+ }
}
/**
* 妫�鏌ユ槸鍚︽墍鏈塻tate閮藉凡瀹屾垚锛�>=2锛�
*/
- private boolean allStatesCompleted(Map<String, Object> stateValues) {
- for (Object value : stateValues.values()) {
+ private boolean allStatesCompleted(Map<String, Object> stateValues, int glassCount) {
+ // 鍙鏌ュ疄闄呮湁鐜荤拑鐨剆tate瀛楁
+ for (int i = 1; i <= glassCount && i <= 6; i++) {
+ String stateField = "state" + i;
+ Object value = stateValues.get(stateField);
Integer state = parseInteger(value);
if (state == null || state < 2) {
return false;
}
}
- return !stateValues.isEmpty();
+ return glassCount > 0;
}
/**
@@ -1583,71 +1995,257 @@
plcDynamicDataService.writePlcData(deviceConfig, payload, serializer);
String taskType = taskInfo.isOutbound ? "鍑虹墖" : "杩涚墖";
- log.info("宸茬粰MES姹囨姤({}浠诲姟): deviceId={}, glassId={}",
- taskType, deviceConfig.getDeviceId(), taskInfo.glassId);
+ String glassIds = taskInfo.glasses.stream()
+ .map(g -> g.glassId)
+ .collect(java.util.stream.Collectors.joining(","));
+ log.info("宸茬粰MES姹囨姤({}浠诲姟): deviceId={}, glassCount={}, glassIds=[{}]",
+ taskType, deviceConfig.getDeviceId(), taskInfo.glasses.size(), glassIds);
- // 绛夊緟MES纭
- waitForMesConfirm(deviceConfig, serializer, taskInfo, logicParams);
-
+ // 澶氳澶囦换鍔″満鏅笅锛屼笉鍦ㄨ繖閲岄樆濉炵瓑寰匨ES纭锛岀敱浠诲姟寮曟搸瀹氭椂璋冪敤checkMesConfirm
} catch (Exception e) {
log.error("缁橫ES姹囨姤寮傚父: deviceId={}", deviceConfig.getDeviceId(), e);
}
}
/**
- * 绛夊緟MES纭
+ * 妫�鏌ES纭鐘舵�侊紙渚涗换鍔″紩鎿庡懆鏈熸�ц皟鐢級
+ * 杩斿洖OperationResult.data涓殑 completed 鏍囧織琛ㄧず鏄惁宸茬‘璁ゅ畬鎴�
*/
- private void waitForMesConfirm(DeviceConfig deviceConfig,
- EnhancedS7Serializer serializer,
- MesTaskInfo taskInfo,
- Map<String, Object> logicParams) {
+ public DevicePlcVO.OperationResult checkMesConfirm(DeviceConfig deviceConfig,
+ Map<String, Object> logicParams) {
+ if (plcDynamicDataService == null || s7SerializerProvider == null) {
+ return DevicePlcVO.OperationResult.builder()
+ .success(false)
+ .message("PlcDynamicDataService鎴朣7SerializerProvider鏈敞鍏�")
+ .build();
+ }
+ EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig);
+ if (serializer == null) {
+ return DevicePlcVO.OperationResult.builder()
+ .success(false)
+ .message("鑾峰彇PLC搴忓垪鍖栧櫒澶辫触")
+ .build();
+ }
+
+ String deviceId = deviceConfig.getDeviceId();
+ MesTaskInfo taskInfo = currentTasks.get(deviceId);
- try {
- // 璇诲彇纭瀛楋紙鍋囪瀛楁鍚嶄负mesConfirm锛�
- Integer maxWaitTime = getLogicParam(logicParams, "mesConfirmTimeoutMs", 30000); // 榛樿30绉�
- long startTime = System.currentTimeMillis();
-
- while (System.currentTimeMillis() - startTime < maxWaitTime) {
- Object confirmValue = plcDynamicDataService.readPlcField(
- deviceConfig, "mesConfirm", serializer);
- Integer confirm = parseInteger(confirmValue);
-
- if (confirm != null && confirm == 1) {
- // MES宸茬‘璁わ紝娓呯┖state鍜屾眹鎶ュ瓧
- clearTaskStates(deviceConfig, serializer);
-
- // 浠诲姟瀹屾垚锛屾仮澶嶄负绌洪棽鐘舵��
- statusManager.updateVehicleStatus(
- deviceConfig.getDeviceId(), VehicleState.IDLE);
- statusManager.clearVehicleTask(deviceConfig.getDeviceId());
-
- // 绉婚櫎浠诲姟
- currentTasks.remove(deviceConfig.getDeviceId());
-
- // 鍋滄浠诲姟鐩戞帶
- handleStopTaskMonitor(deviceConfig);
-
- // 鎭㈠plcRequest=1锛堝彲浠ユ帴鏀舵柊浠诲姟锛�
- Map<String, Object> payload = new HashMap<>();
- payload.put("plcRequest", 1);
- plcDynamicDataService.writePlcData(deviceConfig, payload, serializer);
-
- log.info("MES浠诲姟宸插畬鎴�: deviceId={}, glassId={}",
- deviceConfig.getDeviceId(), taskInfo.glassId);
- return;
+ // 濡傛灉娌℃湁浠诲姟璁板綍锛屼紭鍏堝皾璇曡ˉ鍋挎�у湴妫�鏌ヤ竴娆ES浠诲姟锛堥伩鍏嶅洜鏃跺簭闂涓�鐩磏oTask锛�
+ if (taskInfo == null) {
+ log.info("妫�鏌ES纭鏃舵湭鎵惧埌浠诲姟璁板綍锛屽皾璇曡ˉ鍋挎鏌ES浠诲姟: deviceId={}", deviceId);
+ try {
+ DevicePlcVO.OperationResult checkResult =
+ handleCheckMesTask(deviceConfig, Collections.emptyMap(), logicParams);
+ if (Boolean.TRUE.equals(checkResult.getSuccess())) {
+ taskInfo = currentTasks.get(deviceId);
+ if (taskInfo != null) {
+ log.info("琛ュ伩妫�鏌ES浠诲姟鎴愬姛锛屽凡鍒涘缓浠诲姟璁板綍: deviceId={}", deviceId);
+ } else {
+ log.info("琛ュ伩妫�鏌ES浠诲姟鎵ц鎴愬姛浣嗘湭鍒涘缓浠诲姟璁板綍: deviceId={}, message={}",
+ deviceId, checkResult.getMessage());
+ }
+ } else {
+ log.warn("琛ュ伩妫�鏌ES浠诲姟澶辫触: deviceId={}, message={}", deviceId, checkResult.getMessage());
}
-
- Thread.sleep(500); // 绛夊緟500ms鍚庨噸璇�
+ } catch (Exception e) {
+ log.warn("琛ュ伩妫�鏌ES浠诲姟寮傚父: deviceId={}, error={}", deviceId, e.getMessage());
+ }
+ }
+
+ // 琛ュ伩鍚庝粛鐒舵病鏈変换鍔¤褰曪紝璇存槑MES灏氭湭鎻愪緵鍙墽琛屼换鍔�
+ if (taskInfo == null) {
+ Map<String, Object> waitData = new HashMap<>();
+ waitData.put("completed", false);
+ waitData.put("waiting", true);
+ waitData.put("waitingReason", "noTask");
+ return DevicePlcVO.OperationResult.builder()
+ .success(true)
+ .message("绛夊緟MES鍙戦�佽姹傦紙mesSend=1锛�")
+ .data(waitData)
+ .build();
+ }
+
+ // 鑾峰彇MES纭瓒呮椂閰嶇疆锛堥粯璁�30绉掞級
+ Integer mesConfirmTimeoutMs = getLogicParam(logicParams, "mesConfirmTimeoutMs", 30000);
+
+ Map<String, Object> data = new HashMap<>();
+ try {
+ // 濡傛灉灏氭湭鍚慚ES姹囨姤锛坧lcReport=1锛夛紝鏃犻渶妫�鏌ョ‘璁�
+ if (taskInfo.mesConfirmStartTime == null) {
+ data.put("completed", false);
+ data.put("waiting", true);
+ data.put("waitingReason", "waitingReport");
+ return DevicePlcVO.OperationResult.builder()
+ .success(true)
+ .message("澶ц溅浠诲姟鎵ц涓紝灏氭湭姹囨姤锛屾棤闇�妫�鏌ョ‘璁�")
+ .data(data)
+ .build();
}
- log.warn("绛夊緟MES纭瓒呮椂: deviceId={}, glassId={}",
- deviceConfig.getDeviceId(), taskInfo.glassId);
+ // 妫�鏌ヨ秴鏃�
+ long waitTime = System.currentTimeMillis() - taskInfo.mesConfirmStartTime;
+ if (waitTime > mesConfirmTimeoutMs) {
+ log.warn("MES纭瓒呮椂: deviceId={}, waitTime={}ms, timeout={}ms",
+ deviceId, waitTime, mesConfirmTimeoutMs);
+ data.put("completed", false);
+ data.put("timeout", true);
+ data.put("waitTime", waitTime);
+
+ // 瓒呮椂瑙嗕负浠诲姟澶辫触锛氭竻鐞嗕换鍔$姸鎬佸苟鍋滄鐩戞帶锛岄伩鍏嶇户缁疮鍔犵瓑寰呮椂闂�
+ try {
+ clearTaskStates(deviceConfig, serializer);
+ } catch (Exception e) {
+ log.warn("MES纭瓒呮椂鏃舵竻绌轰换鍔$姸鎬佸け璐�: deviceId={}, error={}", deviceId, e.getMessage());
+ }
+ statusManager.updateVehicleStatus(deviceConfig.getDeviceId(), VehicleState.ERROR);
+ statusManager.clearVehicleTask(deviceConfig.getDeviceId());
+ currentTasks.remove(deviceConfig.getDeviceId());
+ handleStopTaskMonitor(deviceConfig);
+
+ return DevicePlcVO.OperationResult.builder()
+ .success(false)
+ .message(String.format("MES纭瓒呮椂: 绛夊緟鏃堕棿%dms锛岃秴鏃舵椂闂�%dms", waitTime, mesConfirmTimeoutMs))
+ .data(data)
+ .build();
+ }
+ Object confirmValue = plcDynamicDataService.readPlcField(
+ deviceConfig, "mesConfirm", serializer);
+ Integer confirm = parseInteger(confirmValue);
+ boolean completed = confirm != null && confirm == 1;
+ data.put("completed", completed);
+
+ if (completed) {
+ // MES宸茬‘璁わ紝娓呯┖state鍜屾眹鎶ュ瓧
+ clearTaskStates(deviceConfig, serializer);
+
+ // 浠诲姟瀹屾垚锛屾仮澶嶄负绌洪棽鐘舵��
+ statusManager.updateVehicleStatus(
+ deviceConfig.getDeviceId(), VehicleState.IDLE);
+ statusManager.clearVehicleTask(deviceConfig.getDeviceId());
+
+ // 绉婚櫎浠诲姟璁板綍锛堝鏋滄湁锛�
+ currentTasks.remove(deviceConfig.getDeviceId());
+
+ // 鍋滄浠诲姟鐩戞帶
+ handleStopTaskMonitor(deviceConfig);
+
+ // 鎭㈠plcRequest=1锛堝彲浠ユ帴鏀舵柊浠诲姟锛�
+ Map<String, Object> payload = new HashMap<>();
+ payload.put("plcRequest", 1);
+ plcDynamicDataService.writePlcData(deviceConfig, payload, serializer);
+
+ log.info("MES浠诲姟宸茬‘璁ゅ畬鎴�: deviceId={}", deviceConfig.getDeviceId());
+ String taskType = taskInfo.isOutbound ? "鍑虹墖" : "杩涚墖";
+ return DevicePlcVO.OperationResult.builder()
+ .success(true)
+ .message(String.format("%s浠诲姟瀹屾垚锛歁ES宸茬‘璁わ紙mesConfirm=1锛夛紝宸叉竻绌簊tate鍜屾眹鎶ュ瓧锛屽ぇ杞︾┖闂诧紙plcRequest=1锛夛紝鍙互绛夊緟涓嬫浠诲姟", taskType))
+ .data(data)
+ .build();
+ }
+
+ // 鏋勫缓璇︾粏鐨勭瓑寰呮彁绀轰俊鎭�
+ String waitMessage = "绛夊緟MES纭涓紙mesConfirm=0锛�";
+ if (taskInfo.currentStepDesc != null && !taskInfo.currentStepDesc.isEmpty()) {
+ waitMessage = taskInfo.currentStepDesc + "锛�" + waitMessage;
+ } else if (taskInfo.mesConfirmStartTime != null) {
+ long waitMillis = System.currentTimeMillis() - taskInfo.mesConfirmStartTime;
+ waitMessage = String.format("绛夊緟MES纭涓紙mesConfirm=0锛夛紝宸茬瓑寰�%.1f绉�", waitMillis / 1000.0);
+ }
+
+ return DevicePlcVO.OperationResult.builder()
+ .success(true)
+ .message(waitMessage)
+ .data(data)
+ .build();
} catch (Exception e) {
- log.error("绛夊緟MES纭寮傚父: deviceId={}", deviceConfig.getDeviceId(), e);
+ log.error("妫�鏌ES纭鐘舵�佸紓甯�: deviceId={}", deviceConfig.getDeviceId(), e);
+ return DevicePlcVO.OperationResult.builder()
+ .success(false)
+ .message("妫�鏌ES纭鐘舵�佸紓甯�: " + e.getMessage())
+ .data(data)
+ .build();
}
}
+ /**
+ * 璁剧疆鐜荤拑涓虹牬鎹熺姸鎬侊紙state=8锛�
+ * 鐢ㄤ簬娴嬭瘯鍦烘櫙锛屾ā鎷熺幓鐠冪牬鎹�
+ */
+ private DevicePlcVO.OperationResult handleMarkBroken(DeviceConfig deviceConfig,
+ Map<String, Object> params,
+ Map<String, Object> logicParams) {
+ String deviceId = deviceConfig.getDeviceId();
+ MesTaskInfo taskInfo = currentTasks.get(deviceId);
+ if (taskInfo == null) {
+ return DevicePlcVO.OperationResult.builder()
+ .success(false)
+ .message("娌℃湁姝e湪鎵ц鐨勪换鍔�")
+ .build();
+ }
+
+ // 浠庡弬鏁颁腑鑾峰彇瑕佹爣璁颁负鐮存崯鐨勭幓鐠冪储寮曪紙0-based锛�
+ // 鏀寔鍗曚釜绱㈠紩鎴栫储寮曞垪琛�
+ List<Integer> brokenIndices = new ArrayList<>();
+ Object brokenIndexObj = params.get("glassIndex");
+ if (brokenIndexObj != null) {
+ if (brokenIndexObj instanceof List) {
+ @SuppressWarnings("unchecked")
+ List<Object> indexList = (List<Object>) brokenIndexObj;
+ for (Object idx : indexList) {
+ Integer index = parseInteger(idx);
+ if (index != null && index >= 0 && index < taskInfo.glasses.size()) {
+ brokenIndices.add(index);
+ }
+ }
+ } else {
+ Integer index = parseInteger(brokenIndexObj);
+ if (index != null && index >= 0 && index < taskInfo.glasses.size()) {
+ brokenIndices.add(index);
+ }
+ }
+ }
+
+ if (brokenIndices.isEmpty()) {
+ return DevicePlcVO.OperationResult.builder()
+ .success(false)
+ .message("鏈寚瀹氭湁鏁堢殑鐜荤拑绱㈠紩")
+ .build();
+ }
+
+ // 鏍囪涓虹牬鎹�
+ if (taskInfo.brokenGlassIndices == null) {
+ taskInfo.brokenGlassIndices = new ArrayList<>();
+ }
+ for (Integer index : brokenIndices) {
+ if (!taskInfo.brokenGlassIndices.contains(index)) {
+ taskInfo.brokenGlassIndices.add(index);
+ }
+ }
+
+ // 绔嬪嵆鍐欏叆PLC鐨剆tate瀛楁
+ EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig);
+ if (serializer != null) {
+ try {
+ Map<String, Object> payload = new HashMap<>();
+ for (Integer index : brokenIndices) {
+ String stateField = "state" + (index + 1);
+ payload.put(stateField, 8);
+ }
+ plcDynamicDataService.writePlcData(deviceConfig, payload, serializer);
+ log.info("宸叉爣璁扮幓鐠冧负鐮存崯骞跺啓鍏LC: deviceId={}, brokenIndices={}",
+ deviceId, brokenIndices);
+ } catch (Exception e) {
+ log.error("鍐欏叆鐮存崯鐘舵�佸埌PLC澶辫触: deviceId={}, error={}", deviceId, e.getMessage());
+ }
+ }
+
+ return DevicePlcVO.OperationResult.builder()
+ .success(true)
+ .message(String.format("宸叉爣璁扮幓鐠冧负鐮存崯: indices=%s", brokenIndices))
+ .build();
+ }
+
/**
* 娓呯┖浠诲姟鐘舵��
*/
@@ -1696,20 +2294,33 @@
}
/**
- * MES浠诲姟淇℃伅
+ * 鍗曚釜鐜荤拑鐨勪换鍔′俊鎭�
*/
- private static class MesTaskInfo {
+ private static class GlassTaskInfo {
String glassId;
Integer startSlot;
Integer targetSlot;
Integer startPosition;
Integer targetPosition;
+ Integer width;
+ Integer height;
+ Integer thickness;
+ }
+
+ /**
+ * MES浠诲姟淇℃伅锛堝彲鑳藉寘鍚涓幓鐠冿級
+ */
+ private static class MesTaskInfo {
+ List<GlassTaskInfo> glasses = new ArrayList<>(); // 澶氫釜鐜荤拑淇℃伅
Integer currentPosition;
long gotime;
long cartime;
- Integer workLine;
long createdTime;
boolean isOutbound = false; // 鏄惁涓哄嚭鐗囦换鍔★紙false=杩涚墖锛宼rue=鍑虹墖锛�
+ boolean transferPlcRequestCleared = false; // 鏄惁宸叉竻绌哄崸杞珛plcRequest锛堥伩鍏嶉噸澶嶆竻绌猴級
+ List<Integer> brokenGlassIndices = null; // 鏍囪涓虹牬鎹熺殑鐜荤拑绱㈠紩鍒楄〃锛�0-based锛岀敤浜庢祴璇曞満鏅級
+ Long mesConfirmStartTime = null; // MES纭寮�濮嬬瓑寰呯殑鏃堕棿锛堢敤浜庤秴鏃舵娴嬶級
+ String currentStepDesc = null; // 褰撳墠姝ラ鎻忚堪锛堢敤浜庢樉绀鸿缁嗙殑鎵ц鐘舵�侊級
}
/**
@@ -1754,5 +2365,39 @@
Thread.currentThread().interrupt();
}
}
+
+ /**
+ * 閫氱煡鍗ц浆绔嬫壂鐮佽澶囨殏鍋滄垨缁х画
+ * @param params 鍙傛暟锛屽寘鍚玙taskContext寮曠敤
+ * @param pause true=鏆傚仠锛宖alse=缁х画
+ */
+ private void notifyScannerPause(Map<String, Object> params, boolean pause) {
+ if (params == null) {
+ return;
+ }
+
+ Object contextObj = params.get("_taskContext");
+ if (contextObj instanceof TaskExecutionContext) {
+ TaskExecutionContext context = (TaskExecutionContext) contextObj;
+ HorizontalScannerLogicHandler.setPauseFlag(context, pause);
+ log.info("宸查�氱煡鍗ц浆绔嬫壂鐮佽澶噞}: pause={}", pause ? "鏆傚仠" : "缁х画", pause);
+ } else {
+ log.debug("鏈壘鍒癟askExecutionContext锛屾棤娉曢�氱煡鍗ц浆绔嬫壂鐮佽澶囨殏鍋�");
+ }
+ }
+
+ private void clearDynamicTaskStates(DeviceConfig deviceConfig) {
+ if (plcDynamicDataService == null || s7SerializerProvider == null) {
+ return;
+ }
+ try {
+ EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig);
+ if (serializer != null) {
+ clearTaskStates(deviceConfig, serializer);
+ }
+ } catch (Exception e) {
+ log.warn("娓呯┖澶ц溅state瀛楁澶辫触: deviceId={}, error={}", deviceConfig != null ? deviceConfig.getId() : "null", e.getMessage());
+ }
+ }
}
--
Gitblit v1.8.0