| | |
| | | import com.mes.device.entity.DeviceConfig; |
| | | import com.mes.device.service.DevicePlcOperationService; |
| | | import com.mes.device.vo.DevicePlcVO; |
| | | import com.mes.plc.client.PlcClient; |
| | | import com.mes.plc.factory.PlcClientFactory; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | |
| | | |
| | | protected final DevicePlcOperationService devicePlcOperationService; |
| | | protected final ObjectMapper objectMapper = new ObjectMapper(); |
| | | |
| | | // PlcClientFactory 可选注入,如果子类需要直接使用 PlcClient |
| | | protected PlcClientFactory plcClientFactory; |
| | | |
| | | /** |
| | | * 设置 PlcClientFactory(用于子类注入) |
| | | */ |
| | | public void setPlcClientFactory(PlcClientFactory plcClientFactory) { |
| | | this.plcClientFactory = plcClientFactory; |
| | | } |
| | | |
| | | /** |
| | | * 获取 PLC 客户端 |
| | | * |
| | | * @param deviceConfig 设备配置 |
| | | * @return PLC客户端实例,如果获取失败返回null |
| | | */ |
| | | protected PlcClient getPlcClient(DeviceConfig deviceConfig) { |
| | | if (plcClientFactory == null) { |
| | | log.warn("PlcClientFactory未注入,无法获取PLC客户端: deviceId={}", deviceConfig.getId()); |
| | | return null; |
| | | } |
| | | try { |
| | | PlcClient client = plcClientFactory.getClient(deviceConfig); |
| | | if (client == null) { |
| | | log.error("获取PLC客户端失败: deviceId={}", deviceConfig.getId()); |
| | | } |
| | | return client; |
| | | } catch (Exception e) { |
| | | log.error("获取PLC客户端异常: deviceId={}", deviceConfig.getId(), e); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public DevicePlcVO.OperationResult execute(DeviceConfig deviceConfig, String operation, Map<String, Object> params) { |
| | |
| | | import com.mes.interaction.vehicle.model.VehicleState; |
| | | import com.mes.interaction.vehicle.model.VehicleStatus; |
| | | import com.mes.interaction.vehicle.model.VehicleTask; |
| | | import com.mes.s7.enhanced.EnhancedS7Serializer; |
| | | import com.mes.s7.provider.S7SerializerProvider; |
| | | import com.mes.service.PlcDynamicDataService; |
| | | import com.mes.plc.client.PlcClient; |
| | | import com.mes.plc.factory.PlcClientFactory; |
| | | import com.mes.task.model.TaskExecutionContext; |
| | | import com.mes.interaction.workstation.scanner.handler.HorizontalScannerLogicHandler; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | private DeviceStatusService deviceStatusService; |
| | | |
| | | @Autowired(required = false) |
| | | private PlcDynamicDataService plcDynamicDataService; |
| | | |
| | | @Autowired(required = false) |
| | | private S7SerializerProvider s7SerializerProvider; |
| | | private PlcClientFactory plcClientFactory; |
| | | |
| | | // MES字段列表(进片和出片共用同一套协议) |
| | | // 根据协议,使用带数字后缀的字段名(1-6对应6个玻璃位置) |
| | |
| | | @Autowired |
| | | public LoadVehicleLogicHandler( |
| | | DevicePlcOperationService devicePlcOperationService, |
| | | @Qualifier("deviceGlassInfoService") GlassInfoService glassInfoService) { |
| | | @Qualifier("deviceGlassInfoService") GlassInfoService glassInfoService, |
| | | PlcClientFactory plcClientFactory) { |
| | | super(devicePlcOperationService); |
| | | this.glassInfoService = glassInfoService; |
| | | this.plcClientFactory = plcClientFactory; |
| | | // 设置 PlcClientFactory 到基类 |
| | | this.setPlcClientFactory(plcClientFactory); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | |
| | | // 检查是否有待处理的进片或出片任务 |
| | | if (plcDynamicDataService != null && s7SerializerProvider != null) { |
| | | EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig); |
| | | if (serializer != null) { |
| | | // 检查进片任务 |
| | | Map<String, Object> mesData = plcDynamicDataService.readPlcData( |
| | | deviceConfig, MES_FIELDS, serializer); |
| | | Integer mesSend = parseInteger(mesData != null ? mesData.get("mesSend") : null); |
| | | |
| | | // 进片和出片共用mesSend字段,只需检查一次 |
| | | // 如果有待处理的任务,不设置plcRequest(等待任务处理) |
| | | if (mesSend != null && mesSend == 1) { |
| | | log.debug("大车空闲监控: deviceId={}, 检测到待处理任务(mesSend=1),不设置plcRequest", deviceId); |
| | | return; |
| | | } |
| | | PlcClient plcClient = getPlcClient(deviceConfig); |
| | | if (plcClient != null) { |
| | | // 检查进片任务 |
| | | Map<String, Object> mesData = plcClient.readData(MES_FIELDS.toArray(new String[0])); |
| | | Integer mesSend = parseInteger(mesData != null ? mesData.get("mesSend") : null); |
| | | |
| | | // 进片和出片共用mesSend字段,只需检查一次 |
| | | // 如果有待处理的任务,不设置plcRequest(等待任务处理) |
| | | if (mesSend != null && mesSend == 1) { |
| | | log.debug("大车空闲监控: deviceId={}, 检测到待处理任务(mesSend=1),不设置plcRequest", deviceId); |
| | | return; |
| | | } |
| | | } |
| | | |
| | |
| | | Map<String, Object> params, |
| | | Map<String, Object> logicParams) { |
| | | |
| | | if (plcDynamicDataService == null || s7SerializerProvider == null) { |
| | | return DevicePlcVO.OperationResult.builder() |
| | | .success(false) |
| | | .message("PlcDynamicDataService或S7SerializerProvider未注入") |
| | | .build(); |
| | | } |
| | | |
| | | String deviceId = deviceConfig.getDeviceId(); |
| | | EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig); |
| | | if (serializer == null) { |
| | | PlcClient plcClient = getPlcClient(deviceConfig); |
| | | if (plcClient == null) { |
| | | return DevicePlcVO.OperationResult.builder() |
| | | .success(false) |
| | | .message("获取PLC序列化器失败") |
| | | .message("获取PLC客户端失败") |
| | | .build(); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | // 读取MES字段(进片和出片共用) |
| | | Map<String, Object> mesData = plcDynamicDataService.readPlcData( |
| | | deviceConfig, MES_FIELDS, serializer); |
| | | Map<String, Object> mesData = plcClient.readData(MES_FIELDS.toArray(new String[0])); |
| | | if (mesData == null || mesData.isEmpty()) { |
| | | log.warn("读取MES字段失败: deviceId={}, mesData为空或null", deviceId); |
| | | return DevicePlcVO.OperationResult.builder() |
| | |
| | | // 清空plcRequest(表示已接收任务) |
| | | Map<String, Object> payload = new HashMap<>(); |
| | | payload.put("plcRequest", 0); |
| | | plcDynamicDataService.writePlcData(deviceConfig, payload, serializer); |
| | | plcClient.writeData(payload); |
| | | log.info("已清空plcRequest=0: deviceId={}", deviceId); |
| | | |
| | | // 更新车辆状态为执行中 |
| | |
| | | MesTaskInfo taskInfo, |
| | | Map<String, Object> logicParams) { |
| | | |
| | | if (plcDynamicDataService == null || s7SerializerProvider == null) { |
| | | return; |
| | | } |
| | | |
| | | String deviceId = deviceConfig.getDeviceId(); |
| | | EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig); |
| | | if (serializer == null) { |
| | | PlcClient plcClient = getPlcClient(deviceConfig); |
| | | if (plcClient == null) { |
| | | return; |
| | | } |
| | | |
| | |
| | | // 优先检查是否标记为破损(state=8) |
| | | // 检查任务信息中是否标记了该玻璃为破损 |
| | | if (taskInfo.brokenGlassIndices != null && taskInfo.brokenGlassIndices.contains(i)) { |
| | | updateStateIfNeeded(deviceConfig, serializer, stateValues, stateField, 8, taskInfo); |
| | | updateStateIfNeeded(deviceConfig, plcClient, stateValues, stateField, 8, taskInfo); |
| | | log.info("玻璃标记为破损: deviceId={}, stateField={}, glassIndex={}", |
| | | deviceConfig.getDeviceId(), stateField, i); |
| | | continue; |
| | |
| | | |
| | | // 检查超时未完成(state=3) |
| | | if (elapsed >= state3TimeoutTime && (currentState == null || currentState < 2)) { |
| | | updateStateIfNeeded(deviceConfig, serializer, stateValues, stateField, 3, taskInfo); |
| | | updateStateIfNeeded(deviceConfig, plcClient, stateValues, stateField, 3, taskInfo); |
| | | log.warn("任务超时未完成: deviceId={}, stateField={}, elapsed={}ms, expectedTime={}ms", |
| | | deviceConfig.getDeviceId(), stateField, elapsed, state2Time); |
| | | continue; |
| | |
| | | // 正常状态更新 |
| | | if (elapsed >= state1Time && elapsed < state2Time) { |
| | | // state应该为1(上车完成) |
| | | boolean stateChanged = updateStateIfNeeded(deviceConfig, serializer, stateValues, stateField, 1, taskInfo); |
| | | boolean stateChanged = updateStateIfNeeded(deviceConfig, plcClient, stateValues, stateField, 1, taskInfo); |
| | | if (stateChanged) { |
| | | hasStateOne = true; |
| | | currentStepDesc = "玻璃已上车(state=1),正在运输到目标位置"; |
| | |
| | | } |
| | | } else if (elapsed >= state2Time) { |
| | | // state应该为2(运输完成) |
| | | boolean stateChanged = updateStateIfNeeded(deviceConfig, serializer, stateValues, stateField, 2, taskInfo); |
| | | boolean stateChanged = updateStateIfNeeded(deviceConfig, plcClient, stateValues, stateField, 2, taskInfo); |
| | | if (stateChanged) { |
| | | hasStateTwo = true; |
| | | currentStepDesc = "玻璃已到达目标位置(state=2),等待MES确认"; |
| | |
| | | |
| | | // 检查是否所有state都>=2,如果是则给MES汇报 |
| | | if (elapsed >= state2Time && allStatesCompleted(stateValues, glassCount)) { |
| | | reportToMes(deviceConfig, serializer, taskInfo, logicParams); |
| | | reportToMes(deviceConfig, plcClient, taskInfo, logicParams); |
| | | // 记录MES确认开始等待的时间(只记录一次) |
| | | if (taskInfo.mesConfirmStartTime == null) { |
| | | taskInfo.mesConfirmStartTime = System.currentTimeMillis(); |
| | |
| | | * @return 是否发生了状态变化(从非目标状态变为目标状态) |
| | | */ |
| | | private boolean updateStateIfNeeded(DeviceConfig deviceConfig, |
| | | EnhancedS7Serializer serializer, |
| | | PlcClient plcClient, |
| | | Map<String, Object> currentStates, |
| | | String stateField, |
| | | int targetState, |
| | |
| | | try { |
| | | Map<String, Object> payload = new HashMap<>(); |
| | | payload.put(stateField, targetState); |
| | | plcDynamicDataService.writePlcData(deviceConfig, payload, serializer); |
| | | plcClient.writeData(payload); |
| | | |
| | | log.info("任务状态已更新到PLC: deviceId={}, stateField={}, currentState={}, targetState={}", |
| | | deviceConfig.getDeviceId(), stateField, currentState, targetState); |
| | |
| | | * 给MES汇报 |
| | | */ |
| | | private void reportToMes(DeviceConfig deviceConfig, |
| | | EnhancedS7Serializer serializer, |
| | | PlcClient plcClient, |
| | | MesTaskInfo taskInfo, |
| | | Map<String, Object> logicParams) { |
| | | |
| | |
| | | // 设置汇报字 |
| | | Map<String, Object> payload = new HashMap<>(); |
| | | payload.put("plcReport", 1); |
| | | plcDynamicDataService.writePlcData(deviceConfig, payload, serializer); |
| | | plcClient.writeData(payload); |
| | | |
| | | String taskType = taskInfo.isOutbound ? "出片" : "进片"; |
| | | String glassIds = taskInfo.glasses.stream() |
| | |
| | | public DevicePlcVO.OperationResult checkMesConfirm(DeviceConfig deviceConfig, |
| | | Map<String, Object> params, |
| | | Map<String, Object> logicParams) { |
| | | if (plcDynamicDataService == null || s7SerializerProvider == null) { |
| | | return DevicePlcVO.OperationResult.builder() |
| | | .success(false) |
| | | .message("PlcDynamicDataService或S7SerializerProvider未注入") |
| | | .build(); |
| | | } |
| | | EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig); |
| | | if (serializer == null) { |
| | | return DevicePlcVO.OperationResult.builder() |
| | | .success(false) |
| | | .message("获取PLC序列化器失败") |
| | | .build(); |
| | | } |
| | | |
| | | String deviceId = deviceConfig.getDeviceId(); |
| | | PlcClient plcClient = getPlcClient(deviceConfig); |
| | | if (plcClient == null) { |
| | | return DevicePlcVO.OperationResult.builder() |
| | | .success(false) |
| | | .message("获取PLC客户端失败") |
| | | .build(); |
| | | } |
| | | MesTaskInfo taskInfo = currentTasks.get(deviceId); |
| | | |
| | | // 如果没有任务记录,优先尝试补偿性地检查一次MES任务(避免因时序问题一直noTask) |
| | |
| | | |
| | | // 超时视为任务失败:清理任务状态并停止监控,避免继续累加等待时间 |
| | | try { |
| | | clearTaskStates(deviceConfig, serializer); |
| | | clearTaskStates(deviceConfig, plcClient); |
| | | } catch (Exception e) { |
| | | log.warn("MES确认超时时清空任务状态失败: deviceId={}, error={}", deviceId, e.getMessage()); |
| | | } |
| | |
| | | .build(); |
| | | } |
| | | |
| | | Object confirmValue = plcDynamicDataService.readPlcField( |
| | | deviceConfig, "mesConfirm", serializer); |
| | | Integer confirm = parseInteger(confirmValue); |
| | | Map<String, Object> confirmData = plcClient.readData("mesConfirm"); |
| | | Integer confirm = parseInteger(confirmData != null ? confirmData.get("mesConfirm") : null); |
| | | boolean completed = confirm != null && confirm == 1; |
| | | data.put("completed", completed); |
| | | |
| | | if (completed) { |
| | | // MES已确认:本次交互完成(不在设备侧判断“是否还有更多玻璃”,由任务引擎统一编排) |
| | | clearTaskStates(deviceConfig, serializer); |
| | | // MES已确认:本次交互完成(不在设备侧判断"是否还有更多玻璃",由任务引擎统一编排) |
| | | clearTaskStates(deviceConfig, plcClient); |
| | | |
| | | // 记录已完成的任务签名,避免MES未复位时被重复拉起 |
| | | if (taskInfo != null && taskInfo.mesSignature != null) { |
| | |
| | | // 恢复plcRequest=1(可以接收新任务) |
| | | Map<String, Object> payload = new HashMap<>(); |
| | | payload.put("plcRequest", 1); |
| | | plcDynamicDataService.writePlcData(deviceConfig, payload, serializer); |
| | | plcClient.writeData(payload); |
| | | |
| | | log.info("MES任务已确认完成: deviceId={}", deviceConfig.getDeviceId()); |
| | | String taskType = (taskInfo != null && taskInfo.isOutbound) ? "出片" : "进片"; |
| | |
| | | } |
| | | |
| | | // 立即写入PLC的state字段 |
| | | EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig); |
| | | if (serializer != null) { |
| | | PlcClient plcClient = getPlcClient(deviceConfig); |
| | | if (plcClient != null) { |
| | | try { |
| | | Map<String, Object> payload = new HashMap<>(); |
| | | for (Integer index : brokenIndices) { |
| | | String stateField = "state" + (index + 1); |
| | | payload.put(stateField, 8); |
| | | } |
| | | plcDynamicDataService.writePlcData(deviceConfig, payload, serializer); |
| | | log.info("已标记玻璃为破损并写入PLC: deviceId={}, brokenIndices={}", |
| | | deviceId, brokenIndices); |
| | | boolean success = plcClient.writeData(payload); |
| | | if (success) { |
| | | log.info("已标记玻璃为破损并写入PLC: deviceId={}, brokenIndices={}", |
| | | deviceId, brokenIndices); |
| | | } else { |
| | | log.error("写入破损状态到PLC失败: deviceId={}, brokenIndices={}", |
| | | deviceId, brokenIndices); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("写入破损状态到PLC失败: deviceId={}, error={}", deviceId, e.getMessage()); |
| | | } |
| | | } else { |
| | | log.error("获取PLC客户端失败,无法写入破损状态: deviceId={}", deviceId); |
| | | } |
| | | |
| | | return DevicePlcVO.OperationResult.builder() |
| | |
| | | /** |
| | | * 清空任务状态 |
| | | */ |
| | | private void clearTaskStates(DeviceConfig deviceConfig, EnhancedS7Serializer serializer) { |
| | | private void clearTaskStates(DeviceConfig deviceConfig, PlcClient plcClient) { |
| | | try { |
| | | Map<String, Object> payload = new HashMap<>(); |
| | | // 清空state1~6 |
| | |
| | | } |
| | | // 清空汇报字 |
| | | payload.put("plcReport", 0); |
| | | plcDynamicDataService.writePlcData(deviceConfig, payload, serializer); |
| | | plcClient.writeData(payload); |
| | | } catch (Exception e) { |
| | | log.error("清空任务状态异常: deviceId={}", deviceConfig.getDeviceId(), e); |
| | | } |
| | |
| | | } |
| | | |
| | | private void clearDynamicTaskStates(DeviceConfig deviceConfig) { |
| | | if (plcDynamicDataService == null || s7SerializerProvider == null) { |
| | | return; |
| | | } |
| | | try { |
| | | EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig); |
| | | if (serializer != null) { |
| | | clearTaskStates(deviceConfig, serializer); |
| | | PlcClient plcClient = getPlcClient(deviceConfig); |
| | | if (plcClient != null) { |
| | | clearTaskStates(deviceConfig, plcClient); |
| | | } |
| | | } catch (Exception e) { |
| | | log.warn("清空大车state字段失败: deviceId={}, error={}", deviceConfig != null ? deviceConfig.getId() : "null", e.getMessage()); |
| | |
| | | import com.mes.device.vo.DevicePlcVO; |
| | | import com.mes.interaction.workstation.base.WorkstationBaseHandler; |
| | | import com.mes.interaction.workstation.config.WorkstationLogicConfig; |
| | | import com.mes.s7.enhanced.EnhancedS7Serializer; |
| | | import com.mes.s7.provider.S7SerializerProvider; |
| | | import com.mes.service.PlcDynamicDataService; |
| | | import com.mes.plc.client.PlcClient; |
| | | import com.mes.plc.factory.PlcClientFactory; |
| | | import com.mes.task.model.TaskExecutionContext; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | |
| | | |
| | | private static final List<String> MES_FIELDS = Arrays.asList("mesSend", "mesGlassId", "mesWidth", "mesHeight", "workLine"); |
| | | |
| | | private final PlcDynamicDataService plcDynamicDataService; |
| | | private final GlassInfoService glassInfoService; |
| | | private final S7SerializerProvider s7SerializerProvider; |
| | | private final PlcClientFactory plcClientFactory; |
| | | |
| | | public HorizontalScannerLogicHandler(DevicePlcOperationService devicePlcOperationService, |
| | | PlcDynamicDataService plcDynamicDataService, |
| | | GlassInfoService glassInfoService, |
| | | S7SerializerProvider s7SerializerProvider) { |
| | | PlcClientFactory plcClientFactory) { |
| | | super(devicePlcOperationService); |
| | | this.plcDynamicDataService = plcDynamicDataService; |
| | | this.glassInfoService = glassInfoService; |
| | | this.s7SerializerProvider = s7SerializerProvider; |
| | | this.plcClientFactory = plcClientFactory; |
| | | this.setPlcClientFactory(plcClientFactory); |
| | | } |
| | | |
| | | @Override |
| | |
| | | String operation, |
| | | Map<String, Object> params, |
| | | Map<String, Object> logicParams) { |
| | | EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig); |
| | | if (serializer == null) { |
| | | return buildResult(deviceConfig, operation, false, "获取PLC序列化器失败", null); |
| | | PlcClient plcClient = getPlcClient(deviceConfig); |
| | | if (plcClient == null) { |
| | | return buildResult(deviceConfig, operation, false, "获取PLC客户端失败", null); |
| | | } |
| | | |
| | | if ("clearPlc".equalsIgnoreCase(operation) || "reset".equalsIgnoreCase(operation)) { |
| | | return clearPlc(deviceConfig, serializer); |
| | | return clearPlc(deviceConfig, plcClient); |
| | | } |
| | | |
| | | WorkstationLogicConfig config = parseWorkstationConfig(logicParams); |
| | | return executeScan(deviceConfig, config, serializer, params); |
| | | return executeScan(deviceConfig, config, plcClient, params); |
| | | } |
| | | |
| | | private DevicePlcVO.OperationResult executeScan(DeviceConfig deviceConfig, |
| | | WorkstationLogicConfig config, |
| | | EnhancedS7Serializer serializer, |
| | | PlcClient plcClient, |
| | | Map<String, Object> params) { |
| | | try { |
| | | // 从参数中获取玻璃ID(定时器每次只处理一个) |
| | |
| | | } |
| | | |
| | | // 执行单次扫描(定时器会循环调用此方法) |
| | | return executeSingleScan(deviceConfig, config, serializer, inputGlassId, params); |
| | | return executeSingleScan(deviceConfig, config, plcClient, inputGlassId, params); |
| | | } catch (InterruptedException e) { |
| | | Thread.currentThread().interrupt(); |
| | | log.warn("卧转立扫码等待MES数据被中断, deviceId={}", deviceConfig.getId(), e); |
| | |
| | | */ |
| | | private DevicePlcVO.OperationResult executeSingleScan(DeviceConfig deviceConfig, |
| | | WorkstationLogicConfig config, |
| | | EnhancedS7Serializer serializer, |
| | | PlcClient plcClient, |
| | | String inputGlassId, |
| | | Map<String, Object> params) throws InterruptedException { |
| | | // 1. 写入plcRequest=1和plcGlassId(如果提供了玻璃ID) |
| | | triggerScanRequest(deviceConfig, serializer, inputGlassId); |
| | | triggerScanRequest(deviceConfig, plcClient, inputGlassId); |
| | | |
| | | // 2. 等待MES回写mesSend=1以及玻璃信息 |
| | | Map<String, Object> mesData = waitForMesData(deviceConfig, serializer, config); |
| | | Map<String, Object> mesData = waitForMesData(deviceConfig, plcClient, config); |
| | | if (mesData == null || mesData.isEmpty()) { |
| | | log.error("等待MES写入玻璃信息超时: deviceId={}, timeout={}ms", |
| | | deviceConfig.getId(), config.getScanIntervalMs()); |
| | | // 超时也要清空plcRequest |
| | | clearPlcRequestFields(deviceConfig, serializer); |
| | | clearPlcRequestFields(deviceConfig, plcClient); |
| | | return buildResult(deviceConfig, "scanOnce", false, |
| | | String.format("等待MES写入玻璃信息超时(%dms)", config.getScanIntervalMs()), null); |
| | | } |
| | |
| | | String glassId = parseString(mesData.get("mesGlassId")); |
| | | if (!StringUtils.hasText(glassId)) { |
| | | // MES未提供玻璃ID也要清空plcRequest |
| | | clearPlcRequestFields(deviceConfig, serializer); |
| | | clearPlcRequestFields(deviceConfig, plcClient); |
| | | return buildResult(deviceConfig, "scanOnce", false, "MES写区未提供玻璃ID", null); |
| | | } |
| | | // 读取MES尺寸数据:mesWidth=宽,mesHeight=长 |
| | |
| | | Integer workLine = parseInteger(mesData.get("workLine")); |
| | | |
| | | // 4. 清空plcRequest和plcGlassId(只清除PLC字段) |
| | | clearPlcRequestFields(deviceConfig, serializer); |
| | | clearPlcRequestFields(deviceConfig, plcClient); |
| | | |
| | | // 5. 更新玻璃信息状态:将state从0改为1(已扫码交互) |
| | | boolean updated = glassInfoService.updateGlassStateAfterScan(glassId, rawWidth, rawHeight, workLine); |
| | |
| | | } |
| | | |
| | | private DevicePlcVO.OperationResult clearPlc(DeviceConfig deviceConfig, |
| | | EnhancedS7Serializer serializer) { |
| | | PlcClient plcClient) { |
| | | try { |
| | | // 只清空PLC操作区字段(plcRequest、plcGlassId),不清空MES写区字段 |
| | | Map<String, Object> resetFields = new HashMap<>(); |
| | | resetFields.put("plcRequest", 0); |
| | | resetFields.put("plcGlassId", ""); |
| | | plcDynamicDataService.writePlcData(deviceConfig, resetFields, serializer); |
| | | plcClient.writeData(resetFields); |
| | | return buildResult(deviceConfig, "clearPlc", true, "已清空PLC操作区字段(保留MES写区字段)", null); |
| | | } catch (Exception e) { |
| | | log.error("卧转立扫码清空PLC失败, deviceId={}", deviceConfig.getId(), e); |
| | |
| | | /** |
| | | * 触发MES请求:写入plcRequest=1和plcGlassId(如果提供了玻璃ID) |
| | | */ |
| | | private void triggerScanRequest(DeviceConfig deviceConfig, EnhancedS7Serializer serializer, String glassId) { |
| | | private void triggerScanRequest(DeviceConfig deviceConfig, PlcClient plcClient, String glassId) { |
| | | Map<String, Object> writeFields = new HashMap<>(); |
| | | writeFields.put("plcRequest", 1); |
| | | |
| | |
| | | writeFields.put("plcGlassId", glassId); |
| | | } |
| | | |
| | | plcDynamicDataService.writePlcData(deviceConfig, writeFields, serializer); |
| | | plcClient.writeData(writeFields); |
| | | } |
| | | |
| | | /** |
| | | * 清空PLC请求字段:只清除plcRequest和plcGlassId(不清除MES写区字段) |
| | | */ |
| | | private void clearPlcRequestFields(DeviceConfig deviceConfig, EnhancedS7Serializer serializer) { |
| | | private void clearPlcRequestFields(DeviceConfig deviceConfig, PlcClient plcClient) { |
| | | try { |
| | | Map<String, Object> clearFields = new HashMap<>(); |
| | | clearFields.put("plcRequest", 0); |
| | | clearFields.put("plcGlassId", ""); |
| | | plcDynamicDataService.writePlcData(deviceConfig, clearFields, serializer); |
| | | plcClient.writeData(clearFields); |
| | | } catch (Exception e) { |
| | | log.error("清空PLC请求字段失败: deviceId={}", deviceConfig.getId(), e); |
| | | // 不清空不影响主流程,只记录错误 |
| | |
| | | } |
| | | |
| | | private Map<String, Object> waitForMesData(DeviceConfig deviceConfig, |
| | | EnhancedS7Serializer serializer, |
| | | PlcClient plcClient, |
| | | WorkstationLogicConfig config) throws InterruptedException { |
| | | long timeoutMs = Math.max(config.getScanIntervalMs(), 3_000); |
| | | long deadline = System.currentTimeMillis() + timeoutMs; |
| | | int pollInterval = Math.max(200, Math.min(config.getScanIntervalMs() / 5, 1_000)); |
| | | |
| | | while (System.currentTimeMillis() < deadline) { |
| | | Map<String, Object> mesData = plcDynamicDataService.readPlcData(deviceConfig, MES_FIELDS, serializer); |
| | | Map<String, Object> mesData = plcClient.readData(MES_FIELDS.toArray(new String[0])); |
| | | |
| | | if (mesData != null && !mesData.isEmpty()) { |
| | | Integer mesSend = parseInteger(mesData.get("mesSend")); |
| | |
| | | |
| | | // 超时前最后一次尝试读取 |
| | | log.warn("等待MES数据超时: deviceId={}, timeout={}ms", deviceConfig.getId(), timeoutMs); |
| | | Map<String, Object> lastMesData = plcDynamicDataService.readPlcData(deviceConfig, MES_FIELDS, serializer); |
| | | Map<String, Object> lastMesData = plcClient.readData(MES_FIELDS.toArray(new String[0])); |
| | | if (lastMesData != null && !lastMesData.isEmpty()) { |
| | | log.warn("超时前最后一次读取到的数据: deviceId={}, mesData={}", |
| | | deviceConfig.getId(), lastMesData); |
| | |
| | | import com.mes.device.vo.DevicePlcVO; |
| | | import com.mes.interaction.workstation.base.WorkstationBaseHandler; |
| | | import com.mes.interaction.workstation.config.WorkstationLogicConfig; |
| | | import com.mes.s7.enhanced.EnhancedS7Serializer; |
| | | import com.mes.s7.provider.S7SerializerProvider; |
| | | import com.mes.service.PlcDynamicDataService; |
| | | import com.mes.plc.client.PlcClient; |
| | | import com.mes.plc.factory.PlcClientFactory; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Qualifier; |
| | |
| | | @Component |
| | | public class HorizontalTransferLogicHandler extends WorkstationBaseHandler { |
| | | |
| | | private final PlcDynamicDataService plcDynamicDataService; |
| | | private final GlassInfoService glassInfoService; |
| | | private final S7SerializerProvider s7SerializerProvider; |
| | | private final PlcClientFactory plcClientFactory; |
| | | |
| | | @Autowired(required = false) |
| | | private DeviceGlassInfoMapper glassInfoMapper; |
| | |
| | | |
| | | @Autowired |
| | | public HorizontalTransferLogicHandler(DevicePlcOperationService devicePlcOperationService, |
| | | PlcDynamicDataService plcDynamicDataService, |
| | | @Qualifier("deviceGlassInfoService") GlassInfoService glassInfoService, |
| | | S7SerializerProvider s7SerializerProvider) { |
| | | PlcClientFactory plcClientFactory) { |
| | | super(devicePlcOperationService); |
| | | this.plcDynamicDataService = plcDynamicDataService; |
| | | this.glassInfoService = glassInfoService; |
| | | this.s7SerializerProvider = s7SerializerProvider; |
| | | this.plcClientFactory = plcClientFactory; |
| | | // 设置 PlcClientFactory 到基类 |
| | | this.setPlcClientFactory(plcClientFactory); |
| | | } |
| | | |
| | | @Override |
| | |
| | | Map<String, Object> params) { |
| | | |
| | | String deviceId = deviceConfig.getDeviceId(); |
| | | EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig); |
| | | if (serializer == null) { |
| | | PlcClient plcClient = getPlcClient(deviceConfig); |
| | | if (plcClient == null) { |
| | | return buildResult(deviceConfig, "checkAndProcess", false, |
| | | "获取PLC序列化器失败"); |
| | | "获取PLC客户端失败"); |
| | | } |
| | | |
| | | try { |
| | |
| | | |
| | | // 6. 写入PLC(尝试从任务参数中获取卧转立编号) |
| | | DevicePlcVO.OperationResult writeResult = writeBatchToPlc( |
| | | deviceConfig, batch, serializer, logicParams, params); |
| | | deviceConfig, batch, plcClient, logicParams, params); |
| | | |
| | | if (!Boolean.TRUE.equals(writeResult.getSuccess())) { |
| | | return writeResult; |
| | |
| | | private DevicePlcVO.OperationResult writeBatchToPlc( |
| | | DeviceConfig deviceConfig, |
| | | List<GlassInfo> batch, |
| | | EnhancedS7Serializer serializer, |
| | | PlcClient plcClient, |
| | | Map<String, Object> logicParams, |
| | | Map<String, Object> params) { |
| | | |
| | |
| | | payload.put("plcRequest", 1); |
| | | |
| | | try { |
| | | plcDynamicDataService.writePlcData(deviceConfig, payload, serializer); |
| | | plcClient.writeData(payload); |
| | | log.info("批次已写入PLC: deviceId={}, glassCount={}, inPosition={}", |
| | | deviceConfig.getId(), count, inPosition); |
| | | return buildResult(deviceConfig, "writeBatchToPlc", true, |
| | |
| | | */ |
| | | private DevicePlcVO.OperationResult handleClearPlc(DeviceConfig deviceConfig) { |
| | | try { |
| | | EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig); |
| | | if (serializer == null) { |
| | | return buildResult(deviceConfig, "clearPlc", false, "获取PLC序列化器失败"); |
| | | PlcClient plcClient = getPlcClient(deviceConfig); |
| | | if (plcClient == null) { |
| | | return buildResult(deviceConfig, "clearPlc", false, "获取PLC客户端失败"); |
| | | } |
| | | |
| | | Map<String, Object> payload = new HashMap<>(); |
| | |
| | | payload.put("plcRequest", 0); |
| | | payload.put("inPosition", 0); |
| | | |
| | | plcDynamicDataService.writePlcData(deviceConfig, payload, serializer); |
| | | plcClient.writeData(payload); |
| | | log.info("卧转立主体清空PLC字段完成: deviceId={}", deviceConfig.getId()); |
| | | return buildResult(deviceConfig, "clearPlc", true, "已清空卧转立主体PLC字段"); |
| | | } catch (Exception e) { |
| | |
| | | package com.mes.plc.client.impl; |
| | | |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.mes.connect.modbus.ModbusTcpClient; |
| | | import com.mes.device.entity.DeviceConfig; |
| | | import com.mes.plc.client.PlcClient; |
| | |
| | | // 从站地址 |
| | | private final int unitId; |
| | | |
| | | // 设备配置 |
| | | private final DeviceConfig device; |
| | | |
| | | // Modbus客户端实例 |
| | | private ModbusTcpClient modbusClient; |
| | | |
| | |
| | | // 超时时间(毫秒) |
| | | private int timeout = 5000; |
| | | |
| | | // ObjectMapper用于JSON解析 |
| | | private final ObjectMapper objectMapper = new ObjectMapper(); |
| | | |
| | | // 地址映射缓存:字段名 -> Modbus地址 |
| | | private Map<String, String> addressMappingCache; |
| | | |
| | | /** |
| | | * 构造函数 |
| | | * |
| | | * @param device 设备配置 |
| | | */ |
| | | public ModbusPlcClient(DeviceConfig device) { |
| | | this.device = device; |
| | | this.plcIp = device.getPlcIp(); |
| | | this.plcPort = device.getPlcPort() != null ? device.getPlcPort() : 502; |
| | | |
| | |
| | | */ |
| | | private Map<String, Object> parseExtraParams(String extraParamsJson) { |
| | | if (extraParamsJson == null || extraParamsJson.isEmpty()) { |
| | | return null; |
| | | return new HashMap<>(); |
| | | } |
| | | |
| | | try { |
| | |
| | | return Collections.emptyMap(); |
| | | } |
| | | |
| | | if (fields == null || fields.length == 0) { |
| | | return readAllData(); |
| | | } |
| | | |
| | | try { |
| | | // TODO: 实现Modbus读取指定字段数据 |
| | | // 这里暂时返回空Map,后续完善 |
| | |
| | | return Collections.emptyMap(); |
| | | } |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public boolean writeData(Map<String, Object> data) { |
| | | if (!isConnected() && !connect()) { |
| | | log.error("Modbus PLC未连接,无法写入数据: {}:{}", this.plcIp, this.plcPort); |
| | | return false; |
| | | } |
| | | |
| | | if (data == null || data.isEmpty()) { |
| | | log.warn("写入数据为空,跳过操作: deviceId={}", device.getId()); |
| | | return true; |
| | | } |
| | | |
| | | try { |
| | |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public boolean isConnected() { |
| | | try { |
| | |
| | | @Override |
| | | public void setTimeout(int timeout) { |
| | | this.timeout = timeout; |
| | | // ModbusTcpClient不支持直接设置超时,这里仅记录超时时间 |
| | | } |
| | | } |
| | |
| | | import com.mes.device.entity.DeviceConfig; |
| | | import com.mes.device.service.DeviceConfigService; |
| | | import com.mes.device.util.ConfigJsonHelper; |
| | | import com.mes.service.PlcDynamicDataService; |
| | | import com.mes.plc.client.PlcClient; |
| | | import com.mes.plc.factory.PlcClientFactory; |
| | | import com.mes.s7.enhanced.EnhancedS7Serializer; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | |
| | | /** |
| | | * PLC测试写入服务 |
| | | * |
| | | * |
| | | * 基于DeviceConfig的新API,用于模拟PLC行为进行测试 |
| | | * |
| | | * 推荐使用:DevicePlcOperationService(生产环境) |
| | | * |
| | | * |
| | | * @author huang |
| | | * @date 2025/10/29 |
| | | */ |
| | |
| | | |
| | | @Resource |
| | | private DeviceConfigService deviceConfigService; |
| | | |
| | | |
| | | @Resource |
| | | private PlcDynamicDataService plcDynamicDataService; |
| | | |
| | | |
| | | @Resource |
| | | private com.mes.plc.factory.PlcClientFactory plcClientFactory; |
| | | |
| | | private PlcClientFactory plcClientFactory; |
| | | |
| | | private final ObjectMapper objectMapper = new ObjectMapper(); |
| | | private static final TypeReference<Map<String, Object>> MAP_TYPE = new TypeReference<Map<String, Object>>() {}; |
| | | |
| | | private static final int ON = 1; |
| | | private static final int OFF = 0; |
| | | |
| | | |
| | | // 缓存不同设备的S7Serializer实例(保持兼容,逐步迁移) |
| | | private final ConcurrentMap<String, EnhancedS7Serializer> serializerCache = new ConcurrentHashMap<>(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * 根据设备ID模拟PLC发送请求字 |
| | | * |
| | | * |
| | | * @param deviceId 设备ID |
| | | * @return 是否成功 |
| | | */ |
| | |
| | | } |
| | | try { |
| | | // 尝试使用新的PLC客户端工厂 |
| | | com.mes.plc.client.PlcClient plcClient = plcClientFactory.getClient(device); |
| | | PlcClient plcClient = plcClientFactory.getClient(device); |
| | | if (plcClient != null) { |
| | | // 使用新的PLC客户端读取数据 |
| | | Map<String, Object> currentData = plcClient.readAllData(); |
| | |
| | | log.info("当前PLC联机模式为0,停止联机: deviceId={}", deviceId); |
| | | return false; |
| | | } |
| | | |
| | | |
| | | // 检查汇报字,如果为1则重置为0 |
| | | Integer plcReport = parseInteger(currentData.get("plcReport")); |
| | | if (plcReport != null && plcReport == ON) { |
| | | log.info("当前上片PLC汇报字为1,重置为0: deviceId={}", deviceId); |
| | | currentData.put("plcReport", OFF); |
| | | } |
| | | |
| | | |
| | | // 设置请求字为1 |
| | | currentData.put("plcRequest", ON); |
| | | |
| | | |
| | | // 使用新的PLC客户端写入数据 |
| | | boolean success = plcClient.writeData(currentData); |
| | | if (success) { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 如果新客户端失败,回退到旧实现(保持兼容) |
| | | log.warn("新PLC客户端失败,回退到旧实现: deviceId={}", deviceId); |
| | | return simulatePlcRequestByDeviceLegacy(device); |
| | |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 旧版实现:根据设备ID模拟PLC发送请求字 |
| | | * |
| | | * |
| | | * @param device 设备配置 |
| | | * @return 是否成功 |
| | | */ |
| | |
| | | log.error("获取S7Serializer失败: deviceId={}", device.getId()); |
| | | return false; |
| | | } |
| | | |
| | | |
| | | // 使用PlcDynamicDataService读取数据(支持addressMapping) |
| | | Map<String, Object> currentData = plcDynamicDataService.readAllPlcData(device, s7Serializer); |
| | | if (currentData == null || currentData.isEmpty()) { |
| | | log.error("读取PLC数据失败,返回空: deviceId={}", device.getId()); |
| | | return false; |
| | | } |
| | | |
| | | |
| | | // 检查联机状态 |
| | | Object onlineStateObj = currentData.get("onlineState"); |
| | | Integer onlineState = null; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | if (onlineState != null && onlineState == OFF) { |
| | | log.info("当前PLC联机模式为0,停止联机: deviceId={}", device.getId()); |
| | | return false; |
| | | } |
| | | |
| | | |
| | | // 检查汇报字,如果为1则重置为0 |
| | | Object plcReportObj = currentData.get("plcReport"); |
| | | Integer plcReport = null; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | if (plcReport != null && plcReport == ON) { |
| | | log.info("当前上片PLC汇报字为1,重置为0: deviceId={}", device.getId()); |
| | | currentData.put("plcReport", OFF); |
| | | } |
| | | |
| | | |
| | | // 设置请求字为1 |
| | | currentData.put("plcRequest", ON); |
| | | |
| | | |
| | | // 使用PlcDynamicDataService写入数据 |
| | | plcDynamicDataService.writePlcData(device, currentData, s7Serializer); |
| | | |
| | | |
| | | log.info("模拟PLC发送请求字成功(旧版):plcRequest=1, deviceId={}", device.getId()); |
| | | return true; |
| | | } catch (Exception e) { |
| | |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 根据设备ID模拟PLC任务完成汇报 |
| | | * |
| | | * |
| | | * @param deviceId 设备ID |
| | | * @return 是否成功 |
| | | */ |
| | |
| | | return false; |
| | | } |
| | | try { |
| | | EnhancedS7Serializer s7Serializer = getSerializerForDevice(device); |
| | | if (s7Serializer == null) { |
| | | log.error("获取S7Serializer失败: deviceId={}", deviceId); |
| | | return false; |
| | | // 尝试使用新的PLC客户端工厂 |
| | | PlcClient plcClient = plcClientFactory.getClient(device); |
| | | if (plcClient != null) { |
| | | // 使用新的PLC客户端读取数据 |
| | | Map<String, Object> currentData = plcClient.readAllData(); |
| | | if (currentData == null) { |
| | | currentData = new HashMap<>(); |
| | | } |
| | | |
| | | // 设置汇报字为1,请求字清0 |
| | | currentData.put("plcReport", ON); |
| | | currentData.put("plcRequest", OFF); |
| | | |
| | | // 使用新的PLC客户端写入数据 |
| | | boolean success = plcClient.writeData(currentData); |
| | | if (success) { |
| | | log.info("模拟PLC任务完成汇报:plcReport=1, deviceId={}", deviceId); |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | // 使用PlcDynamicDataService读取数据 |
| | | Map<String, Object> currentData = plcDynamicDataService.readAllPlcData(device, s7Serializer); |
| | | if (currentData == null || currentData.isEmpty()) { |
| | | log.error("读取PLC数据失败,返回空: deviceId={}", deviceId); |
| | | return false; |
| | | } |
| | | |
| | | // 设置汇报字为1,请求字清0 |
| | | currentData.put("plcReport", ON); |
| | | currentData.put("plcRequest", OFF); |
| | | currentData.put("mesGlassCount", 10); |
| | | |
| | | // 使用PlcDynamicDataService写入数据 |
| | | plcDynamicDataService.writePlcData(device, currentData, s7Serializer); |
| | | |
| | | log.info("模拟PLC任务完成汇报:plcReport=1, mesGlassCount=10, deviceId={}", deviceId); |
| | | return true; |
| | | |
| | | // 如果新客户端失败,回退到旧实现(保持兼容) |
| | | log.warn("新PLC客户端失败,回退到旧实现: deviceId={}", deviceId); |
| | | return simulatePlcReportByDeviceLegacy(device); |
| | | } catch (Exception e) { |
| | | log.error("根据设备模拟PLC汇报失败: deviceId={}", deviceId, e); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 旧版实现:根据设备模拟PLC任务完成汇报 |
| | | * |
| | | * @param device 设备配置 |
| | | * @return 是否成功 |
| | | */ |
| | | private boolean simulatePlcReportByDeviceLegacy(DeviceConfig device) { |
| | | try { |
| | | EnhancedS7Serializer s7Serializer = getSerializerForDevice(device); |
| | | if (s7Serializer == null) { |
| | | log.error("获取S7Serializer失败: deviceId={}", device.getId()); |
| | | return false; |
| | | } |
| | | |
| | | // 使用PlcDynamicDataService读取数据 |
| | | Map<String, Object> currentData = plcDynamicDataService.readAllPlcData(device, s7Serializer); |
| | | if (currentData == null || currentData.isEmpty()) { |
| | | log.error("读取PLC数据失败,返回空: deviceId={}", device.getId()); |
| | | return false; |
| | | } |
| | | |
| | | // 设置汇报字为1,请求字清0 |
| | | currentData.put("plcReport", ON); |
| | | currentData.put("plcRequest", OFF); |
| | | |
| | | // 使用PlcDynamicDataService写入数据 |
| | | plcDynamicDataService.writePlcData(device, currentData, s7Serializer); |
| | | |
| | | log.info("模拟PLC任务完成汇报(旧版):plcReport=1, deviceId={}", device.getId()); |
| | | return true; |
| | | } catch (Exception e) { |
| | | log.error("根据设备模拟PLC汇报失败(旧版): deviceId={}", device.getId(), e); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据设备ID重置PLC所有状态 |
| | | * |
| | | * |
| | | * @param deviceId 设备ID |
| | | * @return 是否成功 |
| | | */ |
| | |
| | | return false; |
| | | } |
| | | try { |
| | | // 尝试使用新的PLC客户端工厂 |
| | | PlcClient plcClient = plcClientFactory.getClient(device); |
| | | if (plcClient != null) { |
| | | // 构建重置数据 |
| | | Map<String, Object> resetData = new HashMap<>(); |
| | | resetData.put("plcRequest", OFF); |
| | | resetData.put("plcReport", OFF); |
| | | resetData.put("mesSend", OFF); |
| | | resetData.put("mesConfirm", OFF); |
| | | resetData.put("onlineState", ON); |
| | | resetData.put("alarmInfo", OFF); |
| | | |
| | | // 使用新的PLC客户端写入数据 |
| | | boolean success = plcClient.writeData(resetData); |
| | | if (success) { |
| | | log.info("PLC状态已重置, deviceId={}", deviceId); |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | // 如果新客户端失败,回退到旧实现(保持兼容) |
| | | log.warn("新PLC客户端失败,回退到旧实现: deviceId={}", deviceId); |
| | | return resetPlcByDeviceLegacy(device); |
| | | } catch (Exception e) { |
| | | log.error("根据设备重置PLC状态失败: deviceId={}", deviceId, e); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 旧版实现:根据设备重置PLC所有状态 |
| | | * |
| | | * @param device 设备配置 |
| | | * @return 是否成功 |
| | | */ |
| | | private boolean resetPlcByDeviceLegacy(DeviceConfig device) { |
| | | try { |
| | | EnhancedS7Serializer s7Serializer = getSerializerForDevice(device); |
| | | if (s7Serializer == null) { |
| | | log.error("获取S7Serializer失败: deviceId={}", deviceId); |
| | | log.error("获取S7Serializer失败: deviceId={}", device.getId()); |
| | | return false; |
| | | } |
| | | |
| | | |
| | | // 构建重置数据 |
| | | Map<String, Object> resetData = new HashMap<>(); |
| | | resetData.put("plcRequest", OFF); |
| | |
| | | resetData.put("mesSend", OFF); |
| | | resetData.put("mesConfirm", OFF); |
| | | resetData.put("onlineState", ON); |
| | | resetData.put("mesGlassCount", 0); |
| | | resetData.put("alarmInfo", OFF); |
| | | |
| | | |
| | | // 使用PlcDynamicDataService写入数据 |
| | | plcDynamicDataService.writePlcData(device, resetData, s7Serializer); |
| | | |
| | | log.info("PLC状态已重置, deviceId={}", deviceId); |
| | | |
| | | log.info("PLC状态已重置(旧版): deviceId={}", device.getId()); |
| | | return true; |
| | | } catch (Exception e) { |
| | | log.error("根据设备重置PLC状态失败: deviceId={}", deviceId, e); |
| | | log.error("根据设备重置PLC状态失败(旧版): deviceId={}", device.getId(), e); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 根据设备ID读取PLC当前状态 |
| | | * |
| | | * |
| | | * @param deviceId 设备ID |
| | | * @return PLC状态数据 |
| | | */ |
| | |
| | | return null; |
| | | } |
| | | try { |
| | | // 尝试使用新的PLC客户端工厂 |
| | | PlcClient plcClient = plcClientFactory.getClient(device); |
| | | if (plcClient != null) { |
| | | // 使用新的PLC客户端读取所有数据 |
| | | Map<String, Object> data = plcClient.readAllData(); |
| | | log.info("读取PLC状态成功: deviceId={}, dataSize={}", deviceId, data != null ? data.size() : 0); |
| | | return data; |
| | | } |
| | | |
| | | // 如果新客户端失败,回退到旧实现(保持兼容) |
| | | log.warn("新PLC客户端失败,回退到旧实现: deviceId={}", deviceId); |
| | | |
| | | EnhancedS7Serializer s7Serializer = getSerializerForDevice(device); |
| | | if (s7Serializer == null) { |
| | | log.error("获取S7Serializer失败: deviceId={}", deviceId); |
| | |
| | | } |
| | | // 使用PlcDynamicDataService读取所有数据(支持addressMapping) |
| | | Map<String, Object> data = plcDynamicDataService.readAllPlcData(device, s7Serializer); |
| | | log.info("读取PLC状态成功(旧版): deviceId={}, dataSize={}", deviceId, data != null ? data.size() : 0); |
| | | return data; |
| | | } catch (Exception e) { |
| | | log.error("读取设备PLC状态失败: deviceId={}", deviceId, e); |
| | |
| | | } |
| | | |
| | | try { |
| | | // 尝试使用新的PLC客户端工厂 |
| | | PlcClient plcClient = plcClientFactory.getClient(device); |
| | | if (plcClient != null) { |
| | | // 使用新的PLC客户端写入数据 |
| | | boolean success = plcClient.writeData(fieldValues); |
| | | if (success) { |
| | | log.info("写入PLC字段成功: deviceId={}, fields={}", deviceId, fieldValues.keySet()); |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | // 如果新客户端失败,回退到旧实现(保持兼容) |
| | | log.warn("新PLC客户端失败,回退到旧实现: deviceId={}", deviceId); |
| | | |
| | | // 获取对应的S7Serializer(使用设备配置) |
| | | EnhancedS7Serializer s7Serializer = getSerializerForDevice(device); |
| | | if (s7Serializer == null) { |
| | |
| | | // 使用动态数据服务写入字段(基于DeviceConfig) |
| | | plcDynamicDataService.writePlcData(device, fieldValues, s7Serializer); |
| | | |
| | | log.info("写入PLC字段成功: deviceId={}, fields={}", deviceId, fieldValues.keySet()); |
| | | log.info("写入PLC字段成功(旧版): deviceId={}, fields={}", deviceId, fieldValues.keySet()); |
| | | return true; |
| | | } catch (Exception e) { |
| | | log.error("写入PLC字段失败: deviceId={}", deviceId, e); |