huang
2025-12-01 dad0263459b30dbfa75f06dff062a0c85183517b
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("无法解析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);
        // 优先使用运行时参数中的glassIntervalMs(从任务参数传入),如果没有则使用设备配置的
        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);
@@ -311,11 +345,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<>();
@@ -354,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);
        // 注意:glassIntervalMs 的等待应该在批次之间(在TaskExecutionEngine中处理),
        // 而不是在这里等待,因为这里等待会阻塞大车的正常装玻璃流程
        // 如果需要在写入后等待,应该在批次之间等待,让大车有时间处理当前批次的玻璃
        
        // 如果执行成功,更新位置信息到状态,并启动状态监控
        if (Boolean.TRUE.equals(result.getSuccess())) {
@@ -1754,5 +1794,25 @@
            Thread.currentThread().interrupt();
        }
    }
    /**
     * 通知卧转立扫码设备暂停或继续
     * @param params 参数,包含_taskContext引用
     * @param pause true=暂停,false=继续
     */
    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("未找到TaskExecutionContext,无法通知卧转立扫码设备暂停");
        }
    }
}