From dad0263459b30dbfa75f06dff062a0c85183517b Mon Sep 17 00:00:00 2001
From: huang <1532065656@qq.com>
Date: 星期一, 01 十二月 2025 17:01:51 +0800
Subject: [PATCH] 添加卧转立扫码设备交互逻辑,任务流转
---
mes-processes/mes-plcSend/src/main/java/com/mes/interaction/vehicle/handler/LoadVehicleLogicHandler.java | 161 +++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 130 insertions(+), 31 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 aed9919..2599607 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
@@ -16,6 +16,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;
@@ -256,7 +258,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,7 +302,23 @@
// 浠庨�昏緫鍙傛暟涓幏鍙栭厤缃紙浠� extraParams.deviceLogic 璇诲彇锛�
Integer vehicleCapacity = getLogicParam(logicParams, "vehicleCapacity", 6000);
- Integer glassIntervalMs = getLogicParam(logicParams, "glassIntervalMs", 1000);
+ // 浼樺厛浣跨敤杩愯鏃跺弬鏁颁腑鐨刧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);
+ }
Boolean autoFeed = getLogicParam(logicParams, "autoFeed", true);
Integer maxRetryCount = getLogicParam(logicParams, "maxRetryCount", 5);
@@ -302,13 +336,29 @@
Boolean triggerRequest = (Boolean) params.getOrDefault("triggerRequest", autoFeed);
List<GlassInfo> plannedGlasses = planGlassLoading(glassInfos, vehicleCapacity,
- getLogicParam(logicParams, "defaultGlassLength", 2000));
- if (plannedGlasses.isEmpty()) {
+ deviceConfig.getDeviceId());
+ if (plannedGlasses == null) {
+ // 鐜荤拑娌℃湁闀垮害鏃惰繑鍥瀗ull琛ㄧず閿欒
return DevicePlcVO.OperationResult.builder()
.success(false)
- .message("褰撳墠鐜荤拑灏哄瓒呭嚭杞﹁締瀹归噺锛屾棤娉曡杞�")
+ .message("鐜荤拑淇℃伅缂哄皯闀垮害鏁版嵁锛屾棤娉曡繘琛屽閲忚绠椼�傝妫�鏌ES绋嬪簭鏄惁姝g‘鎻愪緵鐜荤拑闀垮害銆�")
.build();
}
+ if (plannedGlasses.isEmpty()) {
+ // 瑁呬笉涓嬶紝閫氱煡鍗ц浆绔嬫壂鐮佽澶囨殏鍋�
+ notifyScannerPause(params, true);
+ log.warn("澶ц溅璁惧瑁呬笉涓嬶紝宸查�氱煡鍗ц浆绔嬫壂鐮佹殏鍋�: deviceId={}, glassCount={}, vehicleCapacity={}",
+ deviceConfig.getId(), glassInfos.size(), vehicleCapacity);
+ return DevicePlcVO.OperationResult.builder()
+ .success(false)
+ .message("褰撳墠鐜荤拑灏哄瓒呭嚭杞﹁締瀹归噺锛屾棤娉曡杞斤紝宸查�氱煡鍗ц浆绔嬫壂鐮佹殏鍋�")
+ .build();
+ }
+
+ // 瑁呭緱涓嬶紝纭繚鍗ц浆绔嬫壂鐮佺户缁繍琛�
+ notifyScannerPause(params, false);
+
+ // 缁х画鎵ц鍘熸湁閫昏緫
// 鏋勫缓鍐欏叆鏁版嵁
Map<String, Object> payload = new HashMap<>();
@@ -347,16 +397,13 @@
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);
+
+ // 娉ㄦ剰锛歡lassIntervalMs 鐨勭瓑寰呭簲璇ュ湪鎵规涔嬮棿锛堝湪TaskExecutionEngine涓鐞嗭級锛�
+ // 鑰屼笉鏄湪杩欓噷绛夊緟锛屽洜涓鸿繖閲岀瓑寰呬細闃诲澶ц溅鐨勬甯歌鐜荤拑娴佺▼
+ // 濡傛灉闇�瑕佸湪鍐欏叆鍚庣瓑寰咃紝搴旇鍦ㄦ壒娆′箣闂寸瓑寰咃紝璁╁ぇ杞︽湁鏃堕棿澶勭悊褰撳墠鎵规鐨勭幓鐠�
// 濡傛灉鎵ц鎴愬姛锛屾洿鏂颁綅缃俊鎭埌鐘舵�侊紝骞跺惎鍔ㄧ姸鎬佺洃鎺�
if (Boolean.TRUE.equals(result.getSuccess())) {
@@ -551,13 +598,6 @@
defaultParams.put("taskMonitorIntervalMs", 1000); // 浠诲姟鐩戞帶闂撮殧锛堟绉掞級
defaultParams.put("mesConfirmTimeoutMs", 30000); // MES纭瓒呮椂锛堟绉掞級
- // 鍑虹墖浠诲姟鐩稿叧閰嶇疆
- // outboundSlotRanges: 鍑虹墖浠诲姟鐨剆tartSlot鑼冨洿锛屼緥濡俒1, 101]琛ㄧず鏍煎瓙1~101閮芥槸鍑虹墖浠诲姟
- // 濡傛灉涓嶉厤缃紝鍒欓�氳繃鍒ゆ柇startSlot鏄惁鍦╬ositionMapping涓潵鍖哄垎杩涚墖/鍑虹墖
- List<Integer> outboundSlotRanges = new ArrayList<>();
- outboundSlotRanges.add(1); // 鏈�灏忔牸瀛愮紪鍙�
- outboundSlotRanges.add(101); // 鏈�澶ф牸瀛愮紪鍙�
- defaultParams.put("outboundSlotRanges", outboundSlotRanges);
// gridPositionMapping: 鏍煎瓙缂栧彿鍒颁綅缃殑鏄犲皠琛紙鍙�夛級
// 濡傛灉涓嶉厤缃紝鍒欐牸瀛愮紪鍙风洿鎺ヤ綔涓轰綅缃��
@@ -644,16 +684,32 @@
return null;
}
+ /**
+ * 瑙勫垝鐜荤拑瑁呰浇
+ * @param source 婧愮幓鐠冨垪琛�
+ * @param vehicleCapacity 杞﹁締瀹归噺
+ * @param deviceId 璁惧ID锛堢敤浜庢棩蹇楋級
+ * @return 瑙勫垝鍚庣殑鐜荤拑鍒楄〃锛屽鏋滅幓鐠冩病鏈夐暱搴﹀垯杩斿洖null锛堢敤浜庢祴璇昅ES绋嬪簭锛�
+ */
private List<GlassInfo> planGlassLoading(List<GlassInfo> source,
int vehicleCapacity,
- Integer defaultGlassLength) {
+ String deviceId) {
List<GlassInfo> planned = new ArrayList<>();
int usedLength = 0;
int capacity = Math.max(vehicleCapacity, 1);
- int fallbackLength = defaultGlassLength != null && defaultGlassLength > 0 ? defaultGlassLength : 2000;
for (GlassInfo info : source) {
- int length = info.getLength() != null && info.getLength() > 0 ? info.getLength() : fallbackLength;
+ Integer glassLength = info.getLength();
+
+ if (glassLength == null || glassLength <= 0) {
+ // 鐜荤拑娌℃湁闀垮害锛岀洿鎺ユ姤閿欙紙鐢ㄤ簬娴嬭瘯MES绋嬪簭锛�
+ log.error("鐜荤拑[{}]缂哄皯闀垮害鏁版嵁锛屾棤娉曡繘琛屽閲忚绠椼�俤eviceId={}锛岃妫�鏌ES绋嬪簭鏄惁姝g‘鎻愪緵鐜荤拑闀垮害銆�",
+ info.getGlassId(), deviceId);
+ return null;
+ }
+
+ int length = glassLength;
+
if (planned.isEmpty()) {
planned.add(info.withLength(length));
usedLength = length;
@@ -1269,15 +1325,19 @@
// 杩欓噷绠�鍖栧鐞嗭細濡傛灉startSlot涓嶅湪positionMapping涓紝涓旀槸鏁板瓧锛屽彲鑳芥槸鏍煎瓙缂栧彿
// 鍙互閫氳繃閰嶇疆鎸囧畾鏍煎瓙缂栧彿鑼冨洿锛屾垨鑰呴�氳繃鏌ユ壘鍚岀粍璁惧鍒ゆ柇
- // 鏂规硶3锛氶�氳繃閰嶇疆鎸囧畾鍑虹墖浠诲姟鐨剆tartSlot鑼冨洿
+ // 鏂规硶3锛氶�氳繃閰嶇疆鎸囧畾杞﹁締杩愬姩鏍煎瓙鑼冨洿锛堝吋瀹规棫閰嶇疆outboundSlotRanges锛�
@SuppressWarnings("unchecked")
- List<Integer> outboundSlotRanges = getLogicParam(logicParams, "outboundSlotRanges", null);
- if (outboundSlotRanges != null && !outboundSlotRanges.isEmpty()) {
- // 濡傛灉閰嶇疆浜嗗嚭鐗噑lot鑼冨洿锛屾鏌tartSlot鏄惁鍦ㄨ寖鍥村唴
- // 渚嬪锛歔1, 101] 琛ㄧず鏍煎瓙1~101閮芥槸鍑虹墖浠诲姟
- if (outboundSlotRanges.size() >= 2) {
- int minSlot = outboundSlotRanges.get(0);
- int maxSlot = outboundSlotRanges.get(1);
+ List<Integer> vehicleSlotRange = getLogicParam(logicParams, "vehicleSlotRange", null);
+ if (vehicleSlotRange == null || vehicleSlotRange.isEmpty()) {
+ // 鍏煎鏃ч厤缃�
+ vehicleSlotRange = getLogicParam(logicParams, "outboundSlotRanges", null);
+ }
+ if (vehicleSlotRange != null && !vehicleSlotRange.isEmpty()) {
+ // 濡傛灉閰嶇疆浜嗚溅杈嗚繍鍔ㄦ牸瀛愯寖鍥达紝妫�鏌tartSlot鏄惁鍦ㄨ寖鍥村唴
+ // 渚嬪锛歔1, 101] 琛ㄧず杞﹁締鍙兘鍦ㄦ牸瀛�1~101涔嬮棿杩愬姩
+ if (vehicleSlotRange.size() >= 2) {
+ int minSlot = vehicleSlotRange.get(0);
+ int maxSlot = vehicleSlotRange.get(1);
if (startSlot >= minSlot && startSlot <= maxSlot) {
return true;
}
@@ -1361,6 +1421,25 @@
*/
private TimeCalculation calculateTime(Integer currentPos, Integer startPos,
Integer targetPos, Map<String, Object> logicParams) {
+ // 楠岃瘉杞﹁締杩愬姩鏍煎瓙鑼冨洿
+ @SuppressWarnings("unchecked")
+ List<Integer> vehicleSlotRange = getLogicParam(logicParams, "vehicleSlotRange", null);
+ if (vehicleSlotRange == null || vehicleSlotRange.isEmpty()) {
+ // 鍏煎鏃ч厤缃�
+ vehicleSlotRange = getLogicParam(logicParams, "outboundSlotRanges", null);
+ }
+ if (vehicleSlotRange != null && vehicleSlotRange.size() >= 2) {
+ int minSlot = vehicleSlotRange.get(0);
+ int maxSlot = vehicleSlotRange.get(1);
+ // 楠岃瘉startPos鍜宼argetPos鏄惁鍦ㄥ厑璁哥殑鑼冨洿鍐�
+ if (startPos != null && (startPos < minSlot || startPos > maxSlot)) {
+ log.warn("璧峰浣嶇疆 {} 瓒呭嚭杞﹁締杩愬姩鏍煎瓙鑼冨洿 [{}, {}]", startPos, minSlot, maxSlot);
+ }
+ if (targetPos != null && (targetPos < minSlot || targetPos > maxSlot)) {
+ log.warn("鐩爣浣嶇疆 {} 瓒呭嚭杞﹁締杩愬姩鏍煎瓙鑼冨洿 [{}, {}]", targetPos, minSlot, maxSlot);
+ }
+ }
+
// 鑾峰彇閫熷害锛堟牸/绉掞紝grid/s锛�
Double speed = getLogicParam(logicParams, "vehicleSpeed", 1.0);
if (speed == null || speed <= 0) {
@@ -1715,5 +1794,25 @@
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锛屾棤娉曢�氱煡鍗ц浆绔嬫壂鐮佽澶囨殏鍋�");
+ }
+ }
}
--
Gitblit v1.8.0