From 8f3a85044b6e4b56a8dd0b104ca023933f1f129c Mon Sep 17 00:00:00 2001
From: huang <1532065656@qq.com>
Date: 星期三, 03 十二月 2025 16:58:36 +0800
Subject: [PATCH] 统一卧转立扫码、卧转立、大车、大理片笼的定时器逻辑和步骤状态;添加设备拓扑图清除数据、联机状态切换按钮,
---
mes-processes/mes-plcSend/src/main/java/com/mes/interaction/vehicle/handler/LoadVehicleLogicHandler.java | 289 +++++++++++++++++++++++++++++++++++++++------------------
1 files changed, 197 insertions(+), 92 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 2599607..62569ad 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;
@@ -49,6 +51,9 @@
@Autowired(required = false)
private DeviceGroupRelationService deviceGroupRelationService;
+
+ @Autowired(required = false)
+ private DeviceStatusService deviceStatusService;
@Autowired(required = false)
private PlcDynamicDataService plcDynamicDataService;
@@ -189,6 +194,9 @@
case "stopTaskMonitor":
result = handleStopTaskMonitor(deviceConfig);
break;
+ case "setOnlineState":
+ result = handleSetOnlineState(deviceConfig, params, logicParams);
+ break;
default:
log.warn("涓嶆敮鎸佺殑鎿嶄綔绫诲瀷: {}", operation);
result = DevicePlcVO.OperationResult.builder()
@@ -221,8 +229,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;
}
/**
@@ -302,23 +316,7 @@
// 浠庨�昏緫鍙傛暟涓幏鍙栭厤缃紙浠� extraParams.deviceLogic 璇诲彇锛�
Integer vehicleCapacity = getLogicParam(logicParams, "vehicleCapacity", 6000);
- // 浼樺厛浣跨敤杩愯鏃跺弬鏁颁腑鐨刧lassIntervalMs锛堜粠浠诲姟鍙傛暟浼犲叆锛夛紝濡傛灉娌℃湁鍒欎娇鐢ㄨ澶囬厤缃殑
- Integer glassIntervalMs = null;
- if (params.containsKey("glassIntervalMs") && params.get("glassIntervalMs") != null) {
- Object intervalObj = params.get("glassIntervalMs");
- if (intervalObj instanceof Number) {
- glassIntervalMs = ((Number) intervalObj).intValue();
- } else if (intervalObj instanceof String) {
- try {
- glassIntervalMs = Integer.parseInt((String) intervalObj);
- } catch (NumberFormatException e) {
- // 蹇界暐
- }
- }
- }
- if (glassIntervalMs == null) {
- glassIntervalMs = getLogicParam(logicParams, "glassIntervalMs", 1000);
- }
+ Integer glassGap = getLogicParam(logicParams, "glassGap", 200); // 鐜荤拑涔嬮棿鐨勭墿鐞嗛棿闅旓紙mm锛夛紝榛樿200mm
Boolean autoFeed = getLogicParam(logicParams, "autoFeed", true);
Integer maxRetryCount = getLogicParam(logicParams, "maxRetryCount", 5);
@@ -335,7 +333,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琛ㄧず閿欒
@@ -371,17 +369,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);
}
// 鑷姩瑙﹀彂璇锋眰瀛�
@@ -401,11 +403,7 @@
DevicePlcVO.OperationResult result = devicePlcOperationService.writeFields(
deviceConfig.getId(), payload, operationName);
- // 娉ㄦ剰锛歡lassIntervalMs 鐨勭瓑寰呭簲璇ュ湪鎵规涔嬮棿锛堝湪TaskExecutionEngine涓鐞嗭級锛�
- // 鑰屼笉鏄湪杩欓噷绛夊緟锛屽洜涓鸿繖閲岀瓑寰呬細闃诲澶ц溅鐨勬甯歌鐜荤拑娴佺▼
- // 濡傛灉闇�瑕佸湪鍐欏叆鍚庣瓑寰咃紝搴旇鍦ㄦ壒娆′箣闂寸瓑寰咃紝璁╁ぇ杞︽湁鏃堕棿澶勭悊褰撳墠鎵规鐨勭幓鐠�
-
- // 濡傛灉鎵ц鎴愬姛锛屾洿鏂颁綅缃俊鎭埌鐘舵�侊紝骞跺惎鍔ㄧ姸鎬佺洃鎺�
+ // 濡傛灉鎵ц鎴愬姛锛屾洿鏂颁綅缃俊鎭埌鐘舵��
if (Boolean.TRUE.equals(result.getSuccess())) {
VehicleStatus status = statusManager.getOrCreateVehicleStatus(
deviceConfig.getDeviceId(), deviceConfig.getDeviceName());
@@ -413,9 +411,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;
@@ -470,6 +475,7 @@
Map<String, Object> payload = new HashMap<>();
payload.put("plcRequest", 0);
payload.put("plcReport", 0);
+ payload.put("onlineState", Boolean.TRUE);
log.info("澶ц溅璁惧閲嶇疆: deviceId={}", deviceConfig.getId());
@@ -484,8 +490,65 @@
statusManager.clearVehicleTask(deviceConfig.getDeviceId());
statusManager.updateVehicleStatus(deviceConfig.getDeviceId(), VehicleState.IDLE);
stopStateMonitoring(deviceConfig.getDeviceId());
+ updateDeviceOnlineStatus(deviceConfig, true);
}
+ 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;
}
@@ -512,6 +575,7 @@
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"));
@@ -532,9 +596,23 @@
statusManager.clearVehicleTask(deviceConfig.getDeviceId());
statusManager.updateVehicleStatus(deviceConfig.getDeviceId(), VehicleState.IDLE);
stopStateMonitoring(deviceConfig.getDeviceId());
+ updateDeviceOnlineStatus(deviceConfig, true);
}
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) {
@@ -572,9 +650,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; // 楠岃瘉閫氳繃
@@ -584,7 +662,7 @@
public String getDefaultLogicParams() {
Map<String, Object> defaultParams = new HashMap<>();
defaultParams.put("vehicleCapacity", 6000);
- defaultParams.put("glassIntervalMs", 1000);
+ defaultParams.put("glassGap", 200); // 鐜荤拑涔嬮棿鐨勭墿鐞嗛棿闅旓紙mm锛夛紝榛樿200mm
defaultParams.put("autoFeed", true);
defaultParams.put("maxRetryCount", 5);
defaultParams.put("defaultGlassLength", 2000);
@@ -687,16 +765,19 @@
/**
* 瑙勫垝鐜荤拑瑁呰浇
* @param source 婧愮幓鐠冨垪琛�
- * @param vehicleCapacity 杞﹁締瀹归噺
+ * @param vehicleCapacity 杞﹁締瀹归噺锛坢m锛�
+ * @param glassGap 鐜荤拑涔嬮棿鐨勭墿鐞嗛棿闅旓紙mm锛夛紝榛樿200mm
* @param deviceId 璁惧ID锛堢敤浜庢棩蹇楋級
* @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();
@@ -711,17 +792,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;
}
@@ -1626,65 +1716,80 @@
log.info("宸茬粰MES姹囨姤({}浠诲姟): deviceId={}, glassId={}",
taskType, deviceConfig.getDeviceId(), taskInfo.glassId);
- // 绛夊緟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();
+ }
+
+ Map<String, Object> data = new HashMap<>();
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;
- }
-
- Thread.sleep(500); // 绛夊緟500ms鍚庨噸璇�
+ 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());
+ return DevicePlcVO.OperationResult.builder()
+ .success(true)
+ .message("MES浠诲姟宸茬‘璁ゅ畬鎴�")
+ .data(data)
+ .build();
}
-
- log.warn("绛夊緟MES纭瓒呮椂: deviceId={}, glassId={}",
- deviceConfig.getDeviceId(), taskInfo.glassId);
-
+
+ return DevicePlcVO.OperationResult.builder()
+ .success(true)
+ .message("绛夊緟MES纭涓�")
+ .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();
}
}
--
Gitblit v1.8.0