package com.mes.plc.factory;
|
|
import com.mes.device.entity.DeviceConfig;
|
import com.mes.plc.client.PlcClient;
|
import com.mes.plc.client.impl.ModbusPlcClient;
|
import com.mes.plc.client.impl.S7PlcClient;
|
import com.mes.service.PlcDynamicDataService;
|
import com.mes.s7.enhanced.EnhancedS7Serializer;
|
import com.mes.s7.provider.S7SerializerProvider;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Component;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentMap;
|
|
/**
|
* PLC客户端工厂
|
* <p>
|
* 根据设备配置创建不同类型的PLC客户端实例
|
* </p>
|
*
|
* @author huang
|
* @date 2025/12/19
|
*/
|
@Slf4j
|
@Component
|
public class PlcClientFactory {
|
// S7序列化器提供者
|
@Autowired
|
private S7SerializerProvider s7SerializerProvider;
|
|
// PLC动态数据服务
|
@Autowired
|
private PlcDynamicDataService plcDynamicDataService;
|
|
// 客户端缓存,提高性能
|
private final ConcurrentMap<String, PlcClient> clientCache = new ConcurrentHashMap<>();
|
|
/**
|
* 根据设备配置创建或获取PLC客户端
|
*
|
* @param device 设备配置
|
* @return PLC客户端实例
|
*/
|
public PlcClient getClient(DeviceConfig device) {
|
if (device == null) {
|
log.error("设备配置为空,无法创建PLC客户端");
|
return null;
|
}
|
|
// 生成缓存键
|
String cacheKey = generateCacheKey(device);
|
|
// 尝试从缓存中获取客户端
|
PlcClient client = clientCache.get(cacheKey);
|
if (client != null && client.isConnected()) {
|
return client;
|
}
|
|
// 缓存中没有或连接已断开,创建新客户端
|
try {
|
client = createClient(device);
|
if (client != null) {
|
// 连接PLC
|
if (client.connect()) {
|
// 将客户端放入缓存
|
clientCache.put(cacheKey, client);
|
log.info("PLC客户端创建成功: cacheKey={}, plcType={}", cacheKey, client.getPlcType());
|
} else {
|
log.error("PLC客户端连接失败: cacheKey={}, plcType={}", cacheKey, client.getPlcType());
|
// 连接失败,不放入缓存
|
client = null;
|
}
|
}
|
} catch (Exception e) {
|
log.error("创建PLC客户端失败: cacheKey={}", cacheKey, e);
|
client = null;
|
}
|
|
return client;
|
}
|
|
/**
|
* 生成缓存键
|
*
|
* @param device 设备配置
|
* @return 缓存键
|
*/
|
private String generateCacheKey(DeviceConfig device) {
|
StringBuilder sb = new StringBuilder();
|
sb.append("device:")
|
.append(device.getId())
|
.append(":")
|
.append(device.getPlcType())
|
.append(":")
|
.append(device.getPlcIp())
|
.append(":")
|
.append(device.getPlcPort());
|
return sb.toString();
|
}
|
|
/**
|
* 根据设备类型创建不同的PLC客户端
|
*
|
* @param device 设备配置
|
* @return PLC客户端实例
|
*/
|
private PlcClient createClient(DeviceConfig device) {
|
if (device == null) {
|
return null;
|
}
|
|
String plcType = device.getPlcType();
|
if (plcType == null || plcType.isEmpty()) {
|
log.error("PLC类型为空,无法创建客户端: deviceId={}", device.getId());
|
return null;
|
}
|
|
// 根据PLC类型创建不同的客户端
|
if (plcType.startsWith("S7")) {
|
// S7协议客户端
|
return createS7Client(device);
|
} else if (plcType.equals("MODBUS")) {
|
// Modbus协议客户端
|
return createModbusClient(device);
|
} else {
|
log.error("不支持的PLC类型: deviceId={}, plcType={}", device.getId(), plcType);
|
return null;
|
}
|
}
|
|
/**
|
* 创建S7协议客户端
|
*
|
* @param device 设备配置
|
* @return S7客户端实例
|
*/
|
private PlcClient createS7Client(DeviceConfig device) {
|
try {
|
// 获取S7序列化器
|
EnhancedS7Serializer s7Serializer = s7SerializerProvider.getSerializer(device);
|
if (s7Serializer == null) {
|
log.error("获取S7Serializer失败: deviceId={}", device.getId());
|
return null;
|
}
|
|
// 创建S7客户端
|
S7PlcClient client = new S7PlcClient(device, s7Serializer);
|
// 设置PLC动态数据服务
|
client.setPlcDynamicDataService(this.plcDynamicDataService);
|
return client;
|
} catch (Exception e) {
|
log.error("创建S7客户端失败: deviceId={}", device.getId(), e);
|
return null;
|
}
|
}
|
|
/**
|
* 创建Modbus协议客户端
|
*
|
* @param device 设备配置
|
* @return Modbus客户端实例
|
*/
|
private PlcClient createModbusClient(DeviceConfig device) {
|
try {
|
// 创建Modbus客户端
|
return new ModbusPlcClient(device);
|
} catch (Exception e) {
|
log.error("创建Modbus客户端失败: deviceId={}", device.getId(), e);
|
return null;
|
}
|
}
|
|
/**
|
* 关闭并移除指定设备的PLC客户端
|
*
|
* @param device 设备配置
|
*/
|
public void removeClient(DeviceConfig device) {
|
if (device == null) {
|
return;
|
}
|
|
String cacheKey = generateCacheKey(device);
|
PlcClient client = clientCache.remove(cacheKey);
|
if (client != null) {
|
client.disconnect();
|
log.info("PLC客户端已移除: cacheKey={}", cacheKey);
|
}
|
}
|
|
/**
|
* 关闭并清除所有PLC客户端
|
*/
|
public void clearAllClients() {
|
log.info("开始清除所有PLC客户端,当前缓存大小: {}", clientCache.size());
|
|
for (PlcClient client : clientCache.values()) {
|
try {
|
client.disconnect();
|
} catch (Exception e) {
|
log.error("关闭PLC客户端失败", e);
|
}
|
}
|
|
clientCache.clear();
|
log.info("所有PLC客户端已清除");
|
}
|
|
/**
|
* 获取客户端缓存大小
|
*
|
* @return 缓存大小
|
*/
|
public int getCacheSize() {
|
return clientCache.size();
|
}
|
}
|