feat: plcs7协议(未测试)
This commit is contained in:
@@ -23,6 +23,13 @@
|
|||||||
<groupId>org.nl</groupId>
|
<groupId>org.nl</groupId>
|
||||||
<artifactId>nl-common</artifactId>
|
<artifactId>nl-common</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- OPC UA 相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.milo</groupId>
|
||||||
|
<artifactId>sdk-client</artifactId>
|
||||||
|
<version>0.6.16</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.nl.iot.core.driver.protocol.plcs7;
|
package org.nl.iot.core.driver.protocol.plcs7;
|
||||||
|
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -10,6 +11,7 @@ import org.nl.common.exception.CommonException;
|
|||||||
import org.nl.iot.core.driver.bo.AttributeBO;
|
import org.nl.iot.core.driver.bo.AttributeBO;
|
||||||
import org.nl.iot.core.driver.entity.RValue;
|
import org.nl.iot.core.driver.entity.RValue;
|
||||||
import org.nl.iot.core.driver.entity.WValue;
|
import org.nl.iot.core.driver.entity.WValue;
|
||||||
|
import org.nl.iot.core.driver.enums.AttributeTypeFlagEnum;
|
||||||
import org.nl.iot.core.driver.protocol.plcs7.com.github.s7.PlcS7PointVariable;
|
import org.nl.iot.core.driver.protocol.plcs7.com.github.s7.PlcS7PointVariable;
|
||||||
import org.nl.iot.core.driver.protocol.plcs7.com.github.s7.api.S7Connector;
|
import org.nl.iot.core.driver.protocol.plcs7.com.github.s7.api.S7Connector;
|
||||||
import org.nl.iot.core.driver.protocol.plcs7.com.github.s7.api.S7Serializer;
|
import org.nl.iot.core.driver.protocol.plcs7.com.github.s7.api.S7Serializer;
|
||||||
@@ -39,6 +41,8 @@ public class PlcS7ProtocolDriverImpl implements DriverCustomService {
|
|||||||
* 仅供参考
|
* 仅供参考
|
||||||
*/
|
*/
|
||||||
private Map<String, MyS7Connector> connectMap;
|
private Map<String, MyS7Connector> connectMap;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
@Override
|
@Override
|
||||||
public void initial() {
|
public void initial() {
|
||||||
connectMap = new ConcurrentHashMap<>(16);
|
connectMap = new ConcurrentHashMap<>(16);
|
||||||
@@ -81,9 +85,80 @@ public class PlcS7ProtocolDriverImpl implements DriverCustomService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean write(Map<String, AttributeBO> driverConfig, Map<String, AttributeBO> pointConfig, IotConnect device, IotConfig point, WValue wValue) {
|
public Boolean write(Map<String, AttributeBO> driverConfig, Map<String, AttributeBO> pointConfig, IotConnect device, IotConfig point, WValue wValue) {
|
||||||
return null;
|
log.debug("Plc S7 Write, device: {}, value: {}", device, wValue);
|
||||||
}
|
MyS7Connector myS7Connector = getS7Connector(String.valueOf(device.getId()), driverConfig);
|
||||||
|
myS7Connector.lock.writeLock().lock();
|
||||||
|
S7Serializer serializer = S7SerializerFactory.buildSerializer(myS7Connector.getConnector());
|
||||||
|
PlcS7PointVariable plcs7PointVariable = getPointVariable(pointConfig, wValue.getType());
|
||||||
|
|
||||||
|
try {
|
||||||
|
store(serializer, plcs7PointVariable, wValue.getType(), wValue.getValue());
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Plc S7 Write Error: {}", e.getMessage());
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
myS7Connector.lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 向 PLC S7 写入数据
|
||||||
|
* <p>
|
||||||
|
* 该方法用于将指定类型的数据写入到 PLC S7 的指定点位。
|
||||||
|
* 1. 根据类型字符串获取对应的 {@link AttributeTypeFlagEnum} 枚举值。
|
||||||
|
* 2. 如果类型不支持, 抛出 {@link UnSupportException} 异常。
|
||||||
|
* 3. 根据类型将字符串值转换为相应的 Java 类型。
|
||||||
|
* 4. 使用 {@link S7Serializer} 将数据写入到 PLC S7 的指定数据块和字节偏移量位置。
|
||||||
|
* <p>
|
||||||
|
* 支持的数据类型包括:
|
||||||
|
* - INT: 整型
|
||||||
|
* - LONG: 长整型
|
||||||
|
* - FLOAT: 单精度浮点型
|
||||||
|
* - DOUBLE: 双精度浮点型
|
||||||
|
* - BOOLEAN: 布尔型
|
||||||
|
* - STRING: 字符串
|
||||||
|
*
|
||||||
|
* @param serializer S7 序列化器, 用于与 PLC S7 进行数据交互
|
||||||
|
* @param plcS7PointVariable PLC S7 点位变量信息, 包含数据块编号, 字节偏移量等
|
||||||
|
* @param type 数据类型字符串, 用于标识要写入的数据类型
|
||||||
|
* @param value 要写入的字符串形式的数据值
|
||||||
|
* @throws CommonException 如果数据类型不支持, 抛出此异常
|
||||||
|
*/
|
||||||
|
private void store(S7Serializer serializer, PlcS7PointVariable plcS7PointVariable, String type, String value) {
|
||||||
|
AttributeTypeFlagEnum valueType = AttributeTypeFlagEnum.ofCode(type);
|
||||||
|
if (Objects.isNull(valueType)) {
|
||||||
|
throw new CommonException("Unsupported type of " + type);
|
||||||
|
}
|
||||||
|
AttributeBO attributeBOConfig = new AttributeBO(value);
|
||||||
|
|
||||||
|
switch (valueType) {
|
||||||
|
case INT:
|
||||||
|
int intValue = attributeBOConfig.getValueByClass(Integer.class);
|
||||||
|
serializer.store(intValue, plcS7PointVariable.getDbNum(), plcS7PointVariable.getByteOffset());
|
||||||
|
break;
|
||||||
|
case LONG:
|
||||||
|
long longValue = attributeBOConfig.getValueByClass(Long.class);
|
||||||
|
serializer.store(longValue, plcS7PointVariable.getDbNum(), plcS7PointVariable.getByteOffset());
|
||||||
|
break;
|
||||||
|
case FLOAT:
|
||||||
|
float floatValue = attributeBOConfig.getValueByClass(Float.class);
|
||||||
|
serializer.store(floatValue, plcS7PointVariable.getDbNum(), plcS7PointVariable.getByteOffset());
|
||||||
|
break;
|
||||||
|
case DOUBLE:
|
||||||
|
double doubleValue = attributeBOConfig.getValueByClass(Double.class);
|
||||||
|
serializer.store(doubleValue, plcS7PointVariable.getDbNum(), plcS7PointVariable.getByteOffset());
|
||||||
|
break;
|
||||||
|
case BOOLEAN:
|
||||||
|
boolean booleanValue = attributeBOConfig.getValueByClass(Boolean.class);
|
||||||
|
serializer.store(booleanValue, plcS7PointVariable.getDbNum(), plcS7PointVariable.getByteOffset());
|
||||||
|
break;
|
||||||
|
case STRING:
|
||||||
|
serializer.store(value, plcS7PointVariable.getDbNum(), plcS7PointVariable.getByteOffset());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 获取 PLC S7 连接器
|
* 获取 PLC S7 连接器
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.junit.runner.RunWith;
|
|||||||
import org.nl.iot.core.driver.bo.AttributeBO;
|
import org.nl.iot.core.driver.bo.AttributeBO;
|
||||||
import org.nl.iot.core.driver.entity.RValue;
|
import org.nl.iot.core.driver.entity.RValue;
|
||||||
import org.nl.iot.core.driver.protocol.modbustcp.ModBusProtocolDriverImpl;
|
import org.nl.iot.core.driver.protocol.modbustcp.ModBusProtocolDriverImpl;
|
||||||
|
import org.nl.iot.core.driver.protocol.plcs7.PlcS7ProtocolDriverImpl;
|
||||||
import org.nl.iot.modular.iot.entity.IotConfig;
|
import org.nl.iot.modular.iot.entity.IotConfig;
|
||||||
import org.nl.iot.modular.iot.entity.IotConnect;
|
import org.nl.iot.modular.iot.entity.IotConnect;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -152,8 +153,81 @@ public class ApiTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PlcS7ProtocolDriverImpl plcS7ProtocolDriver;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void plcS7TestRead() {
|
public void plcS7TestRead() {
|
||||||
|
// 初始化驱动
|
||||||
|
plcS7ProtocolDriver.initial();
|
||||||
|
|
||||||
|
// 构建驱动配置(连接配置)
|
||||||
|
Map<String, AttributeBO> driverConfig = new HashMap<>();
|
||||||
|
driverConfig.put("host", AttributeBO.builder().value("192.168.10.33").build());
|
||||||
|
driverConfig.put("port", AttributeBO.builder().value("102").build());
|
||||||
|
|
||||||
|
// 构建点位配置
|
||||||
|
Map<String, AttributeBO> pointConfig = new HashMap<>();
|
||||||
|
pointConfig.put("dbNum", AttributeBO.builder().value("1").build()); // 数据块编号
|
||||||
|
pointConfig.put("byteOffset", AttributeBO.builder().value("0").build()); // 字节偏移量
|
||||||
|
pointConfig.put("bitOffset", AttributeBO.builder().value("0").build()); // 位偏移量
|
||||||
|
pointConfig.put("blockSize", AttributeBO.builder().value("1").build()); // 数据块大小
|
||||||
|
pointConfig.put("data_type", AttributeBO.builder().value("int").build()); // 数据类型
|
||||||
|
|
||||||
|
// 构建连接对象
|
||||||
|
IotConnect connect = IotConnect.builder()
|
||||||
|
.id(1)
|
||||||
|
.code("PLC_S7_001")
|
||||||
|
.host("192.168.10.33")
|
||||||
|
.port(102)
|
||||||
|
.protocol("plc-s7")
|
||||||
|
.enabled(true)
|
||||||
|
.description("测试PLC S7连接")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 构建配置对象
|
||||||
|
IotConfig config = IotConfig.builder()
|
||||||
|
.id(1)
|
||||||
|
.connectId(1)
|
||||||
|
.alias("pressure")
|
||||||
|
.aliasName("压力传感器")
|
||||||
|
.registerAddress("DB1.DBW0")
|
||||||
|
.dataType("int")
|
||||||
|
.readonly(true)
|
||||||
|
.enabled(true)
|
||||||
|
.description("测试PLC S7数据读取")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try {
|
||||||
|
System.out.println("=== PLC S7读取测试开始 ===");
|
||||||
|
System.out.println("连接地址: " + driverConfig.get("host").getValue() + ":" + driverConfig.get("port").getValue());
|
||||||
|
System.out.println("数据块: DB" + pointConfig.get("dbNum").getValue() +
|
||||||
|
", 偏移: " + pointConfig.get("byteOffset").getValue() +
|
||||||
|
", 类型: " + pointConfig.get("data_type").getValue());
|
||||||
|
|
||||||
|
// 调用read方法进行测试
|
||||||
|
RValue result = plcS7ProtocolDriver.read(driverConfig, pointConfig, connect, config);
|
||||||
|
|
||||||
|
// 检查结果是否为null
|
||||||
|
if (result != null) {
|
||||||
|
System.out.println("\n✓ 读取成功!");
|
||||||
|
System.out.println("连接信息: " + result.getConnect());
|
||||||
|
System.out.println("配置信息: " + result.getConfig());
|
||||||
|
System.out.println("读取值: " + result.getValue());
|
||||||
|
} else {
|
||||||
|
System.err.println("\n✗ 读取失败:返回结果为null");
|
||||||
|
System.err.println("可能原因:");
|
||||||
|
System.err.println("1. PLC设备未连接或IP地址不正确");
|
||||||
|
System.err.println("2. 端口号配置错误(S7-300/400默认102)");
|
||||||
|
System.err.println("3. 数据块(DB)不存在或无访问权限");
|
||||||
|
System.err.println("4. 数据类型或偏移量配置错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("\n=== 测试完成 ===");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("\n✗ 测试异常: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user