| | |
| | | MesTaskInfo existingTask = currentTasks.get(deviceId); |
| | | if (existingTask != null) { |
| | | log.debug("设备已有任务在执行中,跳过检查MES任务: deviceId={}", deviceId); |
| | | // 仍然返回当前任务的玻璃列表,供任务引擎记录/对账本批次 |
| | | List<String> batchIds = new ArrayList<>(); |
| | | if (existingTask.glasses != null) { |
| | | for (GlassTaskInfo g : existingTask.glasses) { |
| | | if (g != null && g.glassId != null && !g.glassId.isEmpty()) { |
| | | batchIds.add(g.glassId); |
| | | } |
| | | } |
| | | } |
| | | return DevicePlcVO.OperationResult.builder() |
| | | .success(true) |
| | | .message("任务执行中,无需重复检查MES任务") |
| | | .data(Collections.singletonMap("waiting", false)) |
| | | .data(new HashMap<String, Object>() {{ |
| | | put("waiting", false); |
| | | put("batchGlassIds", batchIds); |
| | | }}) |
| | | .build(); |
| | | } |
| | | |
| | |
| | | waitData.put("completed", false); |
| | | waitData.put("waiting", true); |
| | | waitData.put("waitingReason", "mesSend=0"); |
| | | waitData.put("batchGlassIds", new ArrayList<>()); |
| | | return DevicePlcVO.OperationResult.builder() |
| | | .success(true) |
| | | .message("等待MES发送请求(mesSend=0)") |
| | |
| | | |
| | | currentTasks.put(deviceId, taskInfo); |
| | | |
| | | // 如果有多设备任务上下文,则记录本次MES下发的玻璃ID列表到上下文,供分批校验使用 |
| | | if (params != null) { |
| | | Object ctxObj = params.get("_taskContext"); |
| | | if (ctxObj instanceof com.mes.task.model.TaskExecutionContext) { |
| | | com.mes.task.model.TaskExecutionContext ctx = (com.mes.task.model.TaskExecutionContext) ctxObj; |
| | | List<String> batchIds = new ArrayList<>(); |
| | | for (GlassTaskInfo g : glasses) { |
| | | if (g != null && g.glassId != null && !g.glassId.isEmpty()) { |
| | | batchIds.add(g.glassId); |
| | | } |
| | | } |
| | | // 1. 记录当前批次的玻璃ID |
| | | ctx.getSharedData().put("currentMesBatchGlassIds", batchIds); |
| | | log.info("记录本次MES批次玻璃列表: deviceId={}, batchIds={}", deviceId, batchIds); |
| | | |
| | | // 2. 初始化总待出片玻璃列表(仅第一次初始化,从任务参数获取) |
| | | if (!ctx.getSharedData().containsKey("initialGlassIds")) { |
| | | // 从任务参数中获取总待出片玻璃ID(核心:总列表来自任务参数,而非MES批次) |
| | | List<String> taskGlassIds = ctx.getParameters().getGlassIds(); |
| | | if (taskGlassIds != null && !taskGlassIds.isEmpty()) { |
| | | ctx.getSharedData().put("initialGlassIds", new ArrayList<>(taskGlassIds)); |
| | | // 初始化已出片列表为空 |
| | | if (!ctx.getSharedData().containsKey("outboundGlassIds")) { |
| | | ctx.getSharedData().put("outboundGlassIds", new ArrayList<>()); |
| | | } |
| | | log.info("初始化总待出片玻璃列表: deviceId={}, taskGlassIds={}", deviceId, taskGlassIds); |
| | | } else { |
| | | log.warn("任务参数中未找到总待出片玻璃ID列表: deviceId={}", deviceId); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 清空plcRequest(表示已接收任务) |
| | | Map<String, Object> payload = new HashMap<>(); |
| | | payload.put("plcRequest", 0); |
| | |
| | | Map<String, Object> successData = new HashMap<>(); |
| | | successData.put("waiting", false); |
| | | successData.put("taskStarted", true); |
| | | // 将本次MES下发的玻璃ID列表通过返回值带回(任务引擎不再依赖_taskContext写入) |
| | | List<String> batchIdsForReturn = new ArrayList<>(); |
| | | for (GlassTaskInfo g : glasses) { |
| | | if (g != null && g.glassId != null && !g.glassId.isEmpty()) { |
| | | batchIdsForReturn.add(g.glassId); |
| | | } |
| | | } |
| | | successData.put("batchGlassIds", batchIdsForReturn); |
| | | |
| | | return DevicePlcVO.OperationResult.builder() |
| | | .success(true) |
| | |
| | | if (taskInfo == null) { |
| | | log.info("检查MES确认时未找到任务记录,尝试补偿检查MES任务: deviceId={}", deviceId); |
| | | try { |
| | | // 关键:补偿检查时也要透传params(包含_taskContext), |
| | | // 否则handleCheckMesTask无法把本批次玻璃ID写入currentMesBatchGlassIds,任务引擎无法累加完成进度 |
| | | Map<String, Object> checkParams = params != null ? params : Collections.emptyMap(); |
| | | DevicePlcVO.OperationResult checkResult = |
| | | handleCheckMesTask(deviceConfig, Collections.emptyMap(), logicParams); |
| | | handleCheckMesTask(deviceConfig, checkParams, logicParams); |
| | | if (Boolean.TRUE.equals(checkResult.getSuccess())) { |
| | | taskInfo = currentTasks.get(deviceId); |
| | | if (taskInfo != null) { |
| | |
| | | data.put("completed", completed); |
| | | |
| | | if (completed) { |
| | | // MES已确认,检查是否还有未出片的玻璃(仅对出片任务) |
| | | boolean hasMoreGlass = false; |
| | | int completedCount = 0; |
| | | int totalCount = 0; |
| | | |
| | | if (taskInfo.isOutbound && params != null) { |
| | | // 从TaskExecutionContext中获取已出片的玻璃ID列表和初始玻璃ID列表 |
| | | Object contextObj = params.get("_taskContext"); |
| | | if (contextObj instanceof com.mes.task.model.TaskExecutionContext) { |
| | | com.mes.task.model.TaskExecutionContext context = |
| | | (com.mes.task.model.TaskExecutionContext) contextObj; |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | List<String> initialGlassIds = (List<String>) context.getSharedData().get("initialGlassIds"); |
| | | @SuppressWarnings("unchecked") |
| | | List<String> outboundGlassIds = (List<String>) context.getSharedData().get("outboundGlassIds"); |
| | | |
| | | if (initialGlassIds != null && !initialGlassIds.isEmpty()) { |
| | | totalCount = initialGlassIds.size(); |
| | | completedCount = (outboundGlassIds != null) ? outboundGlassIds.size() : 0; |
| | | |
| | | // 检查是否所有玻璃都已出片 |
| | | if (outboundGlassIds == null || !outboundGlassIds.containsAll(initialGlassIds)) { |
| | | hasMoreGlass = true; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 如果还有未出片的玻璃,保持plcRequest=1,清理本次任务状态,等待下次交互 |
| | | // 这样第二次交互时,checkMesTask可以检测到mesSend=1,创建新任务,完整地走一遍逻辑 |
| | | if (hasMoreGlass) { |
| | | // 清空state和汇报字(本次交互已完成) |
| | | clearTaskStates(deviceConfig, serializer); |
| | | |
| | | // 注意:不记录lastCompletedMesRecords,因为还有未出片的玻璃,任务未真正完成 |
| | | // 这样第二次交互时,即使MES发送新任务(新的玻璃ID),也不会被误判为旧任务 |
| | | |
| | | // 任务完成,恢复为空闲状态(本次交互已完成) |
| | | 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("出片任务本次交互完成,还有未出片的玻璃,等待下次交互: deviceId={}, completedCount={}, totalCount={}", |
| | | deviceConfig.getDeviceId(), completedCount, totalCount); |
| | | |
| | | String progressMessage = String.format("目前完成出片玻璃数量%d/%d,等待下次交互任务", completedCount, totalCount); |
| | | data.put("completed", false); // 标记为未完成,因为还有未出片的玻璃 |
| | | data.put("waiting", true); |
| | | data.put("waitingReason", "moreGlassToOutbound"); |
| | | data.put("completedCount", completedCount); |
| | | data.put("totalCount", totalCount); |
| | | |
| | | return DevicePlcVO.OperationResult.builder() |
| | | .success(true) |
| | | .message(String.format("出片任务本次交互完成:MES已确认(mesConfirm=1),已清空state和汇报字。%s。大车空闲(plcRequest=1),等待MES发送下次任务", progressMessage)) |
| | | .data(data) |
| | | .build(); |
| | | } |
| | | |
| | | // 所有玻璃都已出片,正常完成流程 |
| | | // MES已确认,清空state和汇报字 |
| | | // MES已确认:本次交互完成(不在设备侧判断“是否还有更多玻璃”,由任务引擎统一编排) |
| | | clearTaskStates(deviceConfig, serializer); |
| | | |
| | | // 记录已完成的任务签名,避免MES未复位时被重复拉起 |
| | | if (taskInfo != null && taskInfo.mesSignature != null) { |
| | | lastCompletedMesRecords.put(deviceId, |
| | | new CompletedMesRecord(taskInfo.mesSignature, System.currentTimeMillis())); |
| | | } |
| | | |
| | | // 任务完成,恢复为空闲状态 |
| | | statusManager.updateVehicleStatus( |
| | |
| | | plcDynamicDataService.writePlcData(deviceConfig, payload, serializer); |
| | | |
| | | log.info("MES任务已确认完成: deviceId={}", deviceConfig.getDeviceId()); |
| | | String taskType = taskInfo.isOutbound ? "出片" : "进片"; |
| | | String taskType = (taskInfo != null && taskInfo.isOutbound) ? "出片" : "进片"; |
| | | return DevicePlcVO.OperationResult.builder() |
| | | .success(true) |
| | | .message(String.format("%s任务完成:MES已确认(mesConfirm=1),已清空state和汇报字,大车空闲(plcRequest=1),可以等待下次任务", taskType)) |
| | | .message(String.format("%s任务交互完成:MES已确认(mesConfirm=1),已清空state和汇报字,大车空闲(plcRequest=1)", taskType)) |
| | | .data(data) |
| | | .build(); |
| | | } |