package com.mes.device.service.impl; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.mes.device.entity.DeviceConfig; import com.mes.device.entity.DeviceGroupConfig; import com.mes.device.service.DeviceCoordinationService; import com.mes.task.model.TaskExecutionContext; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.util.*; import java.util.stream.Collectors; /** * 设备协调服务实现 * * @author mes * @since 2025-01-XX */ @Slf4j @Service @RequiredArgsConstructor public class DeviceCoordinationServiceImpl implements DeviceCoordinationService { private static final TypeReference> MAP_TYPE = new TypeReference>() {}; private final ObjectMapper objectMapper; @Override public CoordinationResult coordinateExecution(DeviceGroupConfig groupConfig, List devices, TaskExecutionContext context) { if (CollectionUtils.isEmpty(devices)) { return CoordinationResult.failure("设备列表为空"); } // 检查所有设备的依赖关系 List unsatisfiedDevices = new ArrayList<>(); for (DeviceConfig device : devices) { DependencyCheckResult checkResult = checkDependencies(device, context); if (!checkResult.isSatisfied()) { unsatisfiedDevices.add(device.getDeviceName() + "(" + device.getDeviceCode() + ")"); log.warn("设备依赖检查失败: deviceId={}, message={}", device.getId(), checkResult.getMessage()); } } if (!unsatisfiedDevices.isEmpty()) { String message = "以下设备的依赖条件不满足: " + String.join(", ", unsatisfiedDevices); return CoordinationResult.failure(message); } // 构建协调元数据 Map metadata = new HashMap<>(); metadata.put("deviceCount", devices.size()); metadata.put("executionOrder", devices.stream() .map(d -> d.getDeviceName() + "(" + d.getDeviceCode() + ")") .collect(Collectors.toList())); return CoordinationResult.success("设备协调成功,可以开始执行", metadata); } @Override public boolean transferData(DeviceConfig fromDevice, DeviceConfig toDevice, Map data, TaskExecutionContext context) { if (fromDevice == null || toDevice == null || data == null || context == null) { log.warn("数据传递参数不完整"); return false; } try { // 将数据存储到共享上下文中 String dataKey = String.format("device_%s_to_%s", fromDevice.getId(), toDevice.getId()); context.getSharedData().put(dataKey, data); // 根据设备类型,提取关键数据并更新上下文 if (DeviceConfig.DeviceType.LOAD_VEHICLE.equals(fromDevice.getDeviceType())) { // 大车设备完成,传递玻璃ID列表 Object glassIds = data.get("glassIds"); if (glassIds instanceof List) { @SuppressWarnings("unchecked") List ids = (List) glassIds; context.setLoadedGlassIds(new ArrayList<>(ids)); log.info("大车设备数据传递: fromDevice={}, toDevice={}, glassIds={}", fromDevice.getDeviceCode(), toDevice.getDeviceCode(), ids); } } else if (DeviceConfig.DeviceType.LARGE_GLASS.equals(fromDevice.getDeviceType())) { // 大理片设备完成,传递处理后的玻璃ID列表 Object glassIds = data.get("glassIds"); if (glassIds instanceof List) { @SuppressWarnings("unchecked") List ids = (List) glassIds; context.setProcessedGlassIds(new ArrayList<>(ids)); log.info("大理片设备数据传递: fromDevice={}, toDevice={}, glassIds={}", fromDevice.getDeviceCode(), toDevice.getDeviceCode(), ids); } } // 存储通用数据 context.getSharedData().put("lastTransferFrom", fromDevice.getId()); context.getSharedData().put("lastTransferTo", toDevice.getId()); context.getSharedData().put("lastTransferTime", System.currentTimeMillis()); return true; } catch (Exception e) { log.error("数据传递失败: fromDevice={}, toDevice={}", fromDevice.getDeviceCode(), toDevice.getDeviceCode(), e); return false; } } @Override public void syncDeviceStatus(DeviceConfig device, DeviceStatus status, TaskExecutionContext context) { if (device == null || context == null) { return; } String statusKey = String.format("device_%s_status", device.getId()); context.getSharedData().put(statusKey, status.name()); context.getSharedData().put(statusKey + "_time", System.currentTimeMillis()); // 更新设备状态映射 @SuppressWarnings("unchecked") Map deviceStatusMap = (Map) context.getSharedData() .computeIfAbsent("deviceStatusMap", k -> new HashMap()); deviceStatusMap.put(device.getId(), status.name()); log.debug("设备状态同步: deviceId={}, status={}", device.getId(), status); } @Override public DependencyCheckResult checkDependencies(DeviceConfig device, TaskExecutionContext context) { if (device == null || context == null) { return DependencyCheckResult.unsatisfied("设备或上下文为空", Collections.emptyList()); } List missingDependencies = new ArrayList<>(); // 检查设备类型特定的依赖 String deviceType = device.getDeviceType(); if (DeviceConfig.DeviceType.LARGE_GLASS.equals(deviceType)) { // 大理片设备需要大车设备先完成 List loadedGlassIds = context.getSafeLoadedGlassIds(); if (CollectionUtils.isEmpty(loadedGlassIds)) { missingDependencies.add("大车设备未完成,缺少玻璃ID列表"); } } // 其他设备类型暂不需要依赖检查 // 检查设备配置中的依赖关系(从extraParams中读取) Map deviceDependencies = getDeviceDependencies(device); if (!CollectionUtils.isEmpty(deviceDependencies)) { for (Map.Entry entry : deviceDependencies.entrySet()) { String depDeviceCode = entry.getKey(); Object depStatus = entry.getValue(); // 检查依赖设备的状态 @SuppressWarnings("unchecked") Map deviceStatusMap = (Map) context.getSharedData() .get("deviceStatusMap"); if (deviceStatusMap != null) { // 这里简化处理,实际应该根据deviceCode查找设备ID // 暂时跳过基于设备代码的依赖检查 } } } if (missingDependencies.isEmpty()) { return DependencyCheckResult.satisfied(); } return DependencyCheckResult.unsatisfied( "设备依赖条件不满足: " + String.join(", ", missingDependencies), missingDependencies ); } @Override public List getDependentDevices(DeviceConfig device, DeviceGroupConfig groupConfig) { if (device == null || groupConfig == null) { return Collections.emptyList(); } // 从设备配置中读取依赖关系 Map deviceDependencies = getDeviceDependencies(device); if (CollectionUtils.isEmpty(deviceDependencies)) { return Collections.emptyList(); } // 这里需要根据deviceCode查找对应的DeviceConfig // 简化实现,返回空列表 // 实际应该查询设备组中的所有设备,然后根据deviceCode匹配 log.debug("获取设备依赖: deviceId={}, dependencies={}", device.getId(), deviceDependencies); return Collections.emptyList(); } /** * 从设备配置中获取依赖关系 */ private Map getDeviceDependencies(DeviceConfig device) { String extraParams = device.getExtraParams(); if (!StringUtils.hasText(extraParams)) { return Collections.emptyMap(); } try { Map extraParamsMap = objectMapper.readValue(extraParams, MAP_TYPE); @SuppressWarnings("unchecked") Map dependencies = (Map) extraParamsMap.get("dependencies"); return dependencies != null ? dependencies : Collections.emptyMap(); } catch (Exception e) { log.warn("解析设备依赖关系失败, deviceId={}", device.getId(), e); return Collections.emptyMap(); } } }