package com.mes.s7.provider; import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType; import com.github.xingshuangs.iot.protocol.s7.service.S7PLC; import com.mes.device.entity.DeviceConfig; import com.mes.s7.enhanced.EnhancedS7Serializer; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; /** * 提供 S7 序列化器的公共工厂,避免各处重复创建/缓存 * @author huang */ @Slf4j @Component public class S7SerializerProvider { private final ConcurrentMap serializerCache = new ConcurrentHashMap<>(); /** * 获取或创建与设备绑定的 S7 序列化器 */ public EnhancedS7Serializer getSerializer(DeviceConfig deviceConfig) { if (deviceConfig == null) { log.error("设备配置为空,无法获取S7序列化器"); return null; } String cacheKey = buildCacheKey(deviceConfig); return serializerCache.computeIfAbsent(cacheKey, key -> createSerializer(deviceConfig)); } /** * 清除指定设备对应的缓存 */ public void clear(DeviceConfig deviceConfig) { if (deviceConfig == null) { return; } serializerCache.remove(buildCacheKey(deviceConfig)); } private String buildCacheKey(DeviceConfig deviceConfig) { if (deviceConfig.getId() != null) { return "device:" + deviceConfig.getId(); } if (deviceConfig.getDeviceCode() != null) { return "device:" + deviceConfig.getDeviceCode(); } return "device:" + Objects.hash(deviceConfig); } private EnhancedS7Serializer createSerializer(DeviceConfig deviceConfig) { try { EPlcType plcType = parsePlcType(deviceConfig.getPlcType()); String plcIp = deviceConfig.getPlcIp(); if (plcIp == null || plcIp.isEmpty()) { log.warn("设备未配置PLC IP,使用默认值 192.168.10.21, deviceId={}", deviceConfig.getId()); plcIp = "192.168.10.21"; } S7PLC s7Plc = new S7PLC(plcType, plcIp); EnhancedS7Serializer serializer = EnhancedS7Serializer.newInstance(s7Plc); if (serializer == null) { log.error("创建EnhancedS7Serializer失败: deviceId={}, plcIp={}, plcType={}", deviceConfig.getId(), plcIp, plcType); } return serializer; } catch (Exception e) { log.error("创建S7序列化器异常: deviceId={}", deviceConfig.getId(), e); return null; } } private EPlcType parsePlcType(String plcTypeValue) { if (plcTypeValue == null || plcTypeValue.isEmpty()) { return EPlcType.S1200; } try { return EPlcType.valueOf(plcTypeValue); } catch (IllegalArgumentException e) { log.warn("未知的PLC类型: {},使用默认类型S1200", plcTypeValue); return EPlcType.S1200; } } }