| | |
| | | switch (operation) { |
| | | case "checkAndProcess": |
| | | case "process": |
| | | return handleCheckAndProcess(deviceConfig, config, logicParams); |
| | | // 这里必须把 params 传进去,以便在多设备任务流程中 |
| | | // 能够通过 _taskContext 将卧转立输出的玻璃ID写入任务上下文 |
| | | return handleCheckAndProcess(deviceConfig, config, logicParams, params); |
| | | case "startMonitor": |
| | | return handleStartMonitor(deviceConfig, config, logicParams); |
| | | case "stopMonitor": |
| | |
| | | private DevicePlcVO.OperationResult handleCheckAndProcess( |
| | | DeviceConfig deviceConfig, |
| | | WorkstationLogicConfig config, |
| | | Map<String, Object> logicParams) { |
| | | Map<String, Object> logicParams, |
| | | Map<String, Object> params) { |
| | | |
| | | String deviceId = deviceConfig.getDeviceId(); |
| | | EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig); |
| | |
| | | log.info("查询到最近扫码的玻璃: deviceId={}, count={}", |
| | | deviceId, recentGlasses.size()); |
| | | |
| | | // 2. 更新缓冲队列和最后扫码时间 |
| | | updateBuffer(deviceId, recentGlasses); |
| | | lastScanTime.put(deviceId, new AtomicLong(System.currentTimeMillis())); |
| | | // 2. 更新缓冲队列;仅在有“新玻璃”加入缓冲时才更新最后扫码时间 |
| | | boolean hasNewGlass = updateBuffer(deviceId, recentGlasses); |
| | | if (hasNewGlass) { |
| | | lastScanTime |
| | | .computeIfAbsent(deviceId, k -> new AtomicLong()) |
| | | .set(System.currentTimeMillis()); |
| | | } |
| | | |
| | | // 3. 检查是否需要立即处理(容量已满或30s内无新玻璃) |
| | | List<GlassBufferItem> buffer = glassBuffer.get(deviceId); |
| | |
| | | return writeResult; |
| | | } |
| | | |
| | | // 7. 从缓冲队列中移除已处理的玻璃 |
| | | // 卧转立批次已成功写入PLC,将本批次玻璃ID写入任务上下文,供大车进片使用 |
| | | try { |
| | | 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> batchGlassIds = batch.stream() |
| | | .map(GlassInfo::getGlassId) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toList()); |
| | | if (!batchGlassIds.isEmpty()) { |
| | | ctx.getSharedData().put("transferReadyGlassIds", |
| | | new java.util.ArrayList<>(batchGlassIds)); |
| | | log.info("卧转立已输出批次玻璃到任务上下文: deviceId={}, glassIds={}", |
| | | deviceConfig.getId(), batchGlassIds); |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | log.warn("卧转立写入任务上下文transferReadyGlassIds失败: deviceId={}", deviceConfig.getId(), e); |
| | | } |
| | | |
| | | // 7. 从缓冲队列中移除已处理的玻璃并更新状态 |
| | | removeProcessedGlasses(deviceId, batch); |
| | | glassInfoService.updateGlassStatus( |
| | | batch.stream().map(GlassInfo::getGlassId).collect(Collectors.toList()), |
| | | GlassInfo.Status.PROCESSED); |
| | | |
| | | String msg = String.format("批次已写入PLC: glassCount=%d, glassIds=%s", |
| | | batch.size(), |
| | |
| | | Date twoMinutesAgo = new Date(System.currentTimeMillis() - 120000); |
| | | |
| | | LambdaQueryWrapper<GlassInfo> wrapper = new LambdaQueryWrapper<>(); |
| | | wrapper.eq(GlassInfo::getStatus, GlassInfo.Status.ACTIVE) |
| | | wrapper.in(GlassInfo::getStatus, GlassInfo.Status.PENDING, GlassInfo.Status.ACTIVE) |
| | | .ge(GlassInfo::getCreatedTime, twoMinutesAgo) |
| | | .orderByDesc(GlassInfo::getCreatedTime) |
| | | .last("LIMIT 20"); // 限制查询数量,避免过多 |
| | |
| | | |
| | | /** |
| | | * 更新缓冲队列 |
| | | * @return 是否有新的玻璃被加入缓冲(用于判断是否刷新 lastScanTime) |
| | | */ |
| | | private void updateBuffer(String deviceId, List<GlassInfo> newGlasses) { |
| | | private boolean updateBuffer(String deviceId, List<GlassInfo> newGlasses) { |
| | | List<GlassBufferItem> buffer = glassBuffer.computeIfAbsent( |
| | | deviceId, k -> new CopyOnWriteArrayList<>()); |
| | | |
| | |
| | | .map(item -> item.glassInfo.getGlassId()) |
| | | .collect(Collectors.toSet()); |
| | | |
| | | boolean hasNewGlass = false; |
| | | for (GlassInfo glass : newGlasses) { |
| | | if (!existingIds.contains(glass.getGlassId())) { |
| | | buffer.add(new GlassBufferItem(glass, System.currentTimeMillis())); |
| | | hasNewGlass = true; |
| | | log.debug("添加玻璃到缓冲队列: deviceId={}, glassId={}", |
| | | deviceId, glass.getGlassId()); |
| | | } |
| | | } |
| | | return hasNewGlass; |
| | | } |
| | | |
| | | /** |
| | |
| | | // 启动监控任务 |
| | | ScheduledFuture<?> future = monitorExecutor.scheduleWithFixedDelay(() -> { |
| | | try { |
| | | handleCheckAndProcess(deviceConfig, config, logicParams); |
| | | // 监控任务不在多设备任务上下文中运行,这里不需要传入 params/_taskContext |
| | | handleCheckAndProcess(deviceConfig, config, logicParams, null); |
| | | } catch (Exception e) { |
| | | log.error("监控任务执行异常: deviceId={}", deviceId, e); |
| | | } |