fix:设备缓存与自动填充/管理
This commit is contained in:
76
nl-iot/src/main/java/org/nl/iot/core/cache/CacheRefreshController.java
vendored
Normal file
76
nl-iot/src/main/java/org/nl/iot/core/cache/CacheRefreshController.java
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
package org.nl.iot.core.cache;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nl.common.pojo.CommonResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 缓存刷新控制器
|
||||
* 提供手动刷新缓存的接口
|
||||
*
|
||||
* @author: lyd
|
||||
* @date: 2026/03/20
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/iot/cache")
|
||||
@Tag(name = "IoT缓存管理")
|
||||
public class CacheRefreshController {
|
||||
|
||||
@Autowired
|
||||
private MetadataCacheManager cacheManager;
|
||||
|
||||
@Operation(summary = "刷新所有缓存")
|
||||
@PostMapping("/refresh/all")
|
||||
public CommonResult<String> refreshAll() {
|
||||
try {
|
||||
cacheManager.refreshAll();
|
||||
return CommonResult.ok("缓存刷新成功");
|
||||
} catch (Exception e) {
|
||||
log.error("刷新缓存失败", e);
|
||||
return CommonResult.error("缓存刷新失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "刷新指定设备缓存")
|
||||
@PostMapping("/refresh/device/{deviceCode}")
|
||||
public CommonResult<String> refreshDevice(@PathVariable String deviceCode) {
|
||||
try {
|
||||
// cacheManager.refreshDevice(deviceCode);
|
||||
// cacheManager.refreshDevicePoints(deviceCode);
|
||||
return CommonResult.ok("设备缓存刷新成功");
|
||||
} catch (Exception e) {
|
||||
log.error("刷新设备缓存失败", e);
|
||||
return CommonResult.error("设备缓存刷新失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "清空所有缓存")
|
||||
@PostMapping("/clear")
|
||||
public CommonResult<String> clearAll() {
|
||||
try {
|
||||
cacheManager.clearAll();
|
||||
return CommonResult.ok("缓存清空成功");
|
||||
} catch (Exception e) {
|
||||
log.error("清空缓存失败", e);
|
||||
return CommonResult.error("缓存清空失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "获取缓存统计信息")
|
||||
@GetMapping("/stats")
|
||||
public CommonResult<Map<String, Object>> getCacheStats() {
|
||||
try {
|
||||
Map<String, Object> stats = cacheManager.getCacheStats();
|
||||
return CommonResult.data(stats);
|
||||
} catch (Exception e) {
|
||||
log.error("获取缓存统计失败", e);
|
||||
return CommonResult.error("获取缓存统计失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
163
nl-iot/src/main/java/org/nl/iot/core/cache/MetadataCacheManager.java
vendored
Normal file
163
nl-iot/src/main/java/org/nl/iot/core/cache/MetadataCacheManager.java
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
package org.nl.iot.core.cache;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nl.iot.core.driver.bo.ConnectSiteDO;
|
||||
import org.nl.iot.core.driver.bo.DeviceConnectionBO;
|
||||
import org.nl.iot.core.driver.bo.DeviceInfoReadCacheDo;
|
||||
import org.nl.iot.core.driver.bo.SiteBO;
|
||||
import org.nl.iot.modular.iot.service.IotConfigService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 元数据缓存管理器
|
||||
* 启动时加载设备和点位信息到内存,避免频繁查询数据库
|
||||
*
|
||||
* @author: lyd
|
||||
* @date: 2026/03/20
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class MetadataCacheManager implements CommandLineRunner {
|
||||
|
||||
@Autowired
|
||||
private IotConfigService configService;
|
||||
|
||||
private final Map<String, DeviceInfoReadCacheDo> deviceInfoCache = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
log.info("开始加载IoT元数据到内存...");
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
loadMetadata();
|
||||
long duration = System.currentTimeMillis() - startTime;
|
||||
log.info("IoT元数据加载完成,耗时: {}ms, 设备信息缓存数: {}",
|
||||
duration, deviceInfoCache.size());
|
||||
} catch (Exception e) {
|
||||
log.error("IoT元数据加载失败", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载所有元数据
|
||||
*/
|
||||
public void loadMetadata() {
|
||||
// 加载设备信息映射
|
||||
loadDeviceInfoMap();
|
||||
}
|
||||
|
||||
private void loadDeviceInfoMap() {
|
||||
// 获取所有设备
|
||||
List<ConnectSiteDO> devices = configService.getAllDeviceInfo();
|
||||
|
||||
if (devices == null || devices.isEmpty()) {
|
||||
log.warn("未查询到设备信息");
|
||||
return;
|
||||
}
|
||||
|
||||
deviceInfoCache.clear();
|
||||
|
||||
// 按 connectCode.deviceCode 分组
|
||||
Map<String, List<ConnectSiteDO>> groupedDevices = devices.stream()
|
||||
.collect(Collectors.groupingBy(device ->
|
||||
device.getConnectCode() + "." + device.getDeviceCode()
|
||||
));
|
||||
|
||||
// 构建缓存
|
||||
for (Map.Entry<String, List<ConnectSiteDO>> entry : groupedDevices.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
List<ConnectSiteDO> deviceList = entry.getValue();
|
||||
|
||||
if (deviceList.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 取第一个元素构建设备连接信息(同一组的连接信息相同)
|
||||
ConnectSiteDO firstDevice = deviceList.get(0);
|
||||
|
||||
// 构建 DeviceConnectionBO
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(firstDevice.getConnectId())
|
||||
.code(firstDevice.getDeviceCode())
|
||||
.host(firstDevice.getHost())
|
||||
.port(firstDevice.getPort())
|
||||
.protocol(firstDevice.getProtocol())
|
||||
.collectMode(firstDevice.getCollectMode())
|
||||
.properties(firstDevice.getProperties())
|
||||
.build();
|
||||
|
||||
// 构建 SiteBO 列表
|
||||
List<SiteBO> siteBOList = deviceList.stream()
|
||||
.map(device -> SiteBO.builder()
|
||||
.deviceCode(device.getDeviceCode())
|
||||
.alias(device.getAlias())
|
||||
.registerAddress(device.getRegisterAddress())
|
||||
.aliasName(device.getAliasName())
|
||||
.dataType(device.getDataType())
|
||||
.readonly(device.getReadonly())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 构建 DeviceInfoReadCacheDo 并存入缓存
|
||||
DeviceInfoReadCacheDo cacheData = DeviceInfoReadCacheDo.builder()
|
||||
.deviceConnectionBO(deviceConnectionBO)
|
||||
.siteBOS(siteBOList)
|
||||
.build();
|
||||
|
||||
deviceInfoCache.put(key, cacheData);
|
||||
}
|
||||
|
||||
log.info("加载设备信息映射完成,数量: {}", deviceInfoCache.size());
|
||||
}
|
||||
|
||||
// ==================== 公共查询方法 ====================
|
||||
|
||||
/**
|
||||
* 根据 connectCode.deviceCode 获取设备信息缓存
|
||||
*/
|
||||
public DeviceInfoReadCacheDo getDeviceInfoCache(String connectCode, String deviceCode) {
|
||||
String key = connectCode + "." + deviceCode;
|
||||
return deviceInfoCache.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有设备信息缓存
|
||||
* 防御性拷贝设计 模式
|
||||
*/
|
||||
public Map<String, DeviceInfoReadCacheDo> getAllDeviceInfoCache() {
|
||||
return new HashMap<>(deviceInfoCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新所有缓存
|
||||
*/
|
||||
public void refreshAll() {
|
||||
log.info("开始刷新所有元数据缓存...");
|
||||
loadMetadata();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空所有缓存
|
||||
*/
|
||||
public void clearAll() {
|
||||
deviceInfoCache.clear();
|
||||
log.info("已清空所有元数据缓存");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存统计信息
|
||||
*/
|
||||
public Map<String, Object> getCacheStats() {
|
||||
Map<String, Object> stats = new HashMap<>();
|
||||
stats.put("deviceInfoCacheCount", deviceInfoCache.size());
|
||||
return stats;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package org.nl.iot.core.driver.bo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* 连接+配置实体
|
||||
* @Author: liyongde
|
||||
* @Date: 2026/3/20 15:08
|
||||
* @Modified By:
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ConnectSiteDO {
|
||||
/** ----- 连接信息 ----- **/
|
||||
@Schema(description = "连接ID")
|
||||
private String connectId;
|
||||
|
||||
@Schema(description = "连接编码")
|
||||
private String connectCode;
|
||||
|
||||
@Schema(description = "主机地址/IP")
|
||||
private String host;
|
||||
|
||||
@Schema(description = "端口")
|
||||
private Integer port;
|
||||
|
||||
@Schema(description = "协议")
|
||||
private String protocol;
|
||||
|
||||
@Schema(description = "采集模式 - 暂时用不到")
|
||||
private String collectMode;
|
||||
|
||||
@Schema(description = "扩展参数(JSON)")
|
||||
private String properties;
|
||||
|
||||
/** ----- 信号点位信息 ----- **/
|
||||
|
||||
@Schema(description = "设备号 - iot_device 的code")
|
||||
private String deviceCode;
|
||||
|
||||
@Schema(description = "信号别名")
|
||||
private String alias;
|
||||
|
||||
@Schema(description = "寄存器地址")
|
||||
private String registerAddress;
|
||||
|
||||
@Schema(description = "别名含义")
|
||||
private String aliasName;
|
||||
|
||||
@Schema(description = "数据类型")
|
||||
private String dataType;
|
||||
|
||||
@Schema(description = "只读(1只读/0可写)")
|
||||
private Boolean readonly;
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import lombok.*;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 设备BO
|
||||
* 设备连接BO
|
||||
* @author: lyd
|
||||
* @date: 2026/3/11
|
||||
*/
|
||||
@@ -16,7 +16,7 @@ import java.io.Serializable;
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DeviceBO implements Serializable {
|
||||
public class DeviceConnectionBO implements Serializable {
|
||||
|
||||
@Schema(description = "连接ID")
|
||||
private String id;
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.nl.iot.core.driver.bo;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 设备读取的缓存实体
|
||||
* @Author: liyongde
|
||||
* @Date: 2026/3/20 14:57
|
||||
* @Modified By:
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DeviceInfoReadCacheDo {
|
||||
|
||||
private DeviceConnectionBO deviceConnectionBO;
|
||||
private List<SiteBO> siteBOS;
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
package org.nl.iot.core.driver.entity;
|
||||
|
||||
import lombok.*;
|
||||
import org.nl.iot.core.driver.bo.DeviceBO;
|
||||
import org.nl.iot.core.driver.bo.DeviceConnectionBO;
|
||||
import org.nl.iot.core.driver.bo.SiteBO;
|
||||
import org.nl.iot.modular.iot.entity.IotConfig;
|
||||
import org.nl.iot.modular.iot.entity.IotConnect;
|
||||
|
||||
/**
|
||||
* 读数据的值
|
||||
@@ -22,7 +20,7 @@ public class RValue {
|
||||
/**
|
||||
* 连接参数
|
||||
*/
|
||||
private DeviceBO deviceBO;
|
||||
private DeviceConnectionBO deviceConnectionBO;
|
||||
|
||||
/**
|
||||
* 配置
|
||||
|
||||
@@ -14,7 +14,7 @@ import org.nl.iot.core.driver.AbstractProtocolDriver;
|
||||
import org.nl.iot.core.driver.ConnectionProtocolMappingManager;
|
||||
import org.nl.iot.core.driver.ProtocolDriver;
|
||||
import org.nl.iot.core.driver.ProtocolType;
|
||||
import org.nl.iot.core.driver.bo.DeviceBO;
|
||||
import org.nl.iot.core.driver.bo.DeviceConnectionBO;
|
||||
import org.nl.iot.core.driver.bo.MetadataEventDTO;
|
||||
import org.nl.iot.core.driver.bo.SiteBO;
|
||||
import org.nl.iot.core.driver.entity.RValue;
|
||||
@@ -67,22 +67,22 @@ public class ModBusProtocolDriverImpl extends AbstractProtocolDriver<PlcConnecti
|
||||
}
|
||||
|
||||
@Override
|
||||
public RValue read(DeviceBO device, SiteBO point) {
|
||||
public RValue read(DeviceConnectionBO device, SiteBO point) {
|
||||
return new RValue(device, point, readValue(getConnector(device), point), "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RValue> batchRead(DeviceBO device, List<SiteBO> points) {
|
||||
public List<RValue> batchRead(DeviceConnectionBO device, List<SiteBO> points) {
|
||||
return batchReadValue(getConnector(device), device, points);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean write(DeviceBO device, WValue wValue) {
|
||||
public Boolean write(DeviceConnectionBO device, WValue wValue) {
|
||||
return writeValue(getConnector(device), device, wValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WResponse> batchWrite(DeviceBO device, List<WValue> wValue) {
|
||||
public List<WResponse> batchWrite(DeviceConnectionBO device, List<WValue> wValue) {
|
||||
return batchWriteValue(getConnector(device), wValue);
|
||||
}
|
||||
|
||||
@@ -122,13 +122,13 @@ public class ModBusProtocolDriverImpl extends AbstractProtocolDriver<PlcConnecti
|
||||
/**
|
||||
* 获取 Modbus Master 连接器
|
||||
*/
|
||||
private PlcConnection getConnector(DeviceBO deviceBO) {
|
||||
log.debug("Modbus Tcp Connection Info: {}", deviceBO);
|
||||
PlcConnection modbusMaster = connectMap.get(deviceBO.getId());
|
||||
private PlcConnection getConnector(DeviceConnectionBO deviceConnectionBO) {
|
||||
log.debug("Modbus Tcp Connection Info: {}", deviceConnectionBO);
|
||||
PlcConnection modbusMaster = connectMap.get(deviceConnectionBO.getId());
|
||||
try {
|
||||
if (Objects.isNull(modbusMaster)) {
|
||||
modbusMaster = new DefaultPlcDriverManager().getConnection(ModBusTcpUtils.buildModBusPlcUrl(deviceBO));
|
||||
createModBusConnection(deviceBO.getId(), modbusMaster);
|
||||
modbusMaster = new DefaultPlcDriverManager().getConnection(ModBusTcpUtils.buildModBusPlcUrl(deviceConnectionBO));
|
||||
createModBusConnection(deviceConnectionBO.getId(), modbusMaster);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
@@ -168,7 +168,7 @@ public class ModBusProtocolDriverImpl extends AbstractProtocolDriver<PlcConnecti
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public List<RValue> batchReadValue(PlcConnection modbusMaster, DeviceBO deviceBO, List<SiteBO> points) {
|
||||
public List<RValue> batchReadValue(PlcConnection modbusMaster, DeviceConnectionBO deviceConnectionBO, List<SiteBO> points) {
|
||||
// 1. 解析配置
|
||||
PlcReadRequest.Builder readBuilder = doBuildReadRequest(modbusMaster, points);
|
||||
// 3. 执行请求
|
||||
@@ -182,16 +182,16 @@ public class ModBusProtocolDriverImpl extends AbstractProtocolDriver<PlcConnecti
|
||||
PlcResponseCode responseCode = readResponse.getResponseCode(point.getAlias());
|
||||
// 4. 校验响应码
|
||||
if (responseCode != PlcResponseCode.OK) {
|
||||
list.add(new RValue(deviceBO, point, null, String.format(
|
||||
list.add(new RValue(deviceConnectionBO, point, null, String.format(
|
||||
"读取Modbus失败,设备编码:%s,地址:%s,响应码:%s", point.getAlias(), point.getRegisterAddress(), responseCode
|
||||
)));
|
||||
continue;
|
||||
}
|
||||
// 5. 取值并转换
|
||||
PlcValue plcValue = readResponse.getPlcValue(point.getAlias());
|
||||
list.add(new RValue(deviceBO, point, PlcValueConvertUtil.convertPlcValueToString(plcValue, point.getDataType()), ""));
|
||||
list.add(new RValue(deviceConnectionBO, point, PlcValueConvertUtil.convertPlcValueToString(plcValue, point.getDataType()), ""));
|
||||
} catch (Exception e) {
|
||||
list.add(new RValue(deviceBO, point, null, String.format(
|
||||
list.add(new RValue(deviceConnectionBO, point, null, String.format(
|
||||
"读取Modbus失败,设备编码:%s,地址:%s,响应码:%s", point.getAlias(), point.getRegisterAddress(), e.getMessage()
|
||||
)));
|
||||
}
|
||||
@@ -253,7 +253,7 @@ public class ModBusProtocolDriverImpl extends AbstractProtocolDriver<PlcConnecti
|
||||
* 向 Modbus 设备写入点位值
|
||||
*/
|
||||
@SneakyThrows
|
||||
private boolean writeValue(PlcConnection modbusMaster, DeviceBO deviceBO, WValue wValue) {
|
||||
private boolean writeValue(PlcConnection modbusMaster, DeviceConnectionBO deviceConnectionBO, WValue wValue) {
|
||||
// 1. 解析配置
|
||||
PlcWriteRequest.Builder writeRequestBuilder = doBuildWriteRequest(modbusMaster, Collections.singletonList(wValue));
|
||||
PlcWriteRequest writeRequest = writeRequestBuilder.build();
|
||||
|
||||
@@ -3,11 +3,8 @@ package org.nl.iot.core.driver.protocol.modbustcp.util;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.plc4x.java.DefaultPlcDriverManager;
|
||||
import org.apache.plc4x.java.api.PlcConnection;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.nl.common.exception.CommonException;
|
||||
import org.nl.iot.core.driver.bo.DeviceBO;
|
||||
import org.nl.iot.core.driver.bo.DeviceConnectionBO;
|
||||
import org.nl.iot.core.driver.entity.WValue;
|
||||
import org.nl.iot.core.driver.protocol.modbustcp.com.serotonin.modbus4j.ModbusMaster;
|
||||
import org.nl.iot.core.driver.protocol.modbustcp.com.serotonin.modbus4j.code.DataType;
|
||||
@@ -248,15 +245,15 @@ public class ModBusTcpUtils {
|
||||
}
|
||||
|
||||
|
||||
public static String buildModBusPlcUrl(DeviceBO deviceBO) {
|
||||
String host = deviceBO.getHost();
|
||||
public static String buildModBusPlcUrl(DeviceConnectionBO deviceConnectionBO) {
|
||||
String host = deviceConnectionBO.getHost();
|
||||
if (host == null || host.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("设备IP/域名(host)不能为空");
|
||||
}
|
||||
JSONObject pointConfig = JSONObject.parseObject(deviceBO.getProperties());
|
||||
JSONObject pointConfig = JSONObject.parseObject(deviceConnectionBO.getProperties());
|
||||
int slaveId = pointConfig.getIntValue("slaveId");
|
||||
int finalSlaveId = ObjectUtil.isEmpty(slaveId) ? DEFAULT_SLAVE_ID : slaveId;
|
||||
return MODBUS_CONN_PRX + host.trim() + ":" + deviceBO.getPort()
|
||||
return MODBUS_CONN_PRX + host.trim() + ":" + deviceConnectionBO.getPort()
|
||||
+ "?default-unit-identifier=" + finalSlaveId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.nl.iot.core.driver.AbstractProtocolDriver;
|
||||
import org.nl.iot.core.driver.ConnectionProtocolMappingManager;
|
||||
import org.nl.iot.core.driver.ProtocolDriver;
|
||||
import org.nl.iot.core.driver.ProtocolType;
|
||||
import org.nl.iot.core.driver.bo.DeviceBO;
|
||||
import org.nl.iot.core.driver.bo.DeviceConnectionBO;
|
||||
import org.nl.iot.core.driver.bo.MetadataEventDTO;
|
||||
import org.nl.iot.core.driver.bo.SiteBO;
|
||||
import org.nl.iot.core.driver.entity.RValue;
|
||||
@@ -71,35 +71,35 @@ public class OpcDaProtocolDriverImpl extends AbstractProtocolDriver<Server> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RValue read(DeviceBO device, SiteBO point) {
|
||||
public RValue read(DeviceConnectionBO device, SiteBO point) {
|
||||
return new RValue(device, point, readValue(getConnector(device), device, point), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean write(DeviceBO device, WValue wValue) {
|
||||
public Boolean write(DeviceConnectionBO device, WValue wValue) {
|
||||
Server server = getConnector(device);
|
||||
return writeValue(server, device, wValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RValue> batchRead(DeviceBO device, List<SiteBO> point) {
|
||||
public List<RValue> batchRead(DeviceConnectionBO device, List<SiteBO> point) {
|
||||
return batchReadValue(getConnector(device), device, point);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WResponse> batchWrite(DeviceBO device, List<WValue> wValues) {
|
||||
public List<WResponse> batchWrite(DeviceConnectionBO device, List<WValue> wValues) {
|
||||
return batchWriteValue(device, wValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 OPC DA 服务器连接
|
||||
*/
|
||||
private Server getConnector(DeviceBO deviceBO) {
|
||||
log.debug("Opc Da Server Connection Info {}", deviceBO);
|
||||
JSONObject config = JSONObject.parseObject(deviceBO.getProperties());
|
||||
Server server = connectMap.get(deviceBO.getId());
|
||||
private Server getConnector(DeviceConnectionBO deviceConnectionBO) {
|
||||
log.debug("Opc Da Server Connection Info {}", deviceConnectionBO);
|
||||
JSONObject config = JSONObject.parseObject(deviceConnectionBO.getProperties());
|
||||
Server server = connectMap.get(deviceConnectionBO.getId());
|
||||
if (Objects.isNull(server)) {
|
||||
String host = deviceBO.getHost();
|
||||
String host = deviceConnectionBO.getHost();
|
||||
String clsId = config.getString("clsId");
|
||||
String user = config.getString("username");
|
||||
String password = ObjectUtil.isEmpty(config.get("password")) ? "" : config.getString("password");
|
||||
@@ -107,9 +107,9 @@ public class OpcDaProtocolDriverImpl extends AbstractProtocolDriver<Server> {
|
||||
server = new Server(connectionInformation, Executors.newSingleThreadScheduledExecutor());
|
||||
try {
|
||||
server.connect();
|
||||
addOpcDaConnection(deviceBO.getId(), server);
|
||||
addOpcDaConnection(deviceConnectionBO.getId(), server);
|
||||
} catch (AlreadyConnectedException | UnknownHostException | JIException e) {
|
||||
removeConnection(deviceBO.getId());
|
||||
removeConnection(deviceConnectionBO.getId());
|
||||
log.error("Connect opc da server error: {}", e.getMessage(), e);
|
||||
throw new CommonException(e.getMessage());
|
||||
}
|
||||
@@ -129,9 +129,9 @@ public class OpcDaProtocolDriverImpl extends AbstractProtocolDriver<Server> {
|
||||
* 该方法通过给定的 OPC DA 服务器和位号配置, 获取对应的 Item 对象, 并读取其值。
|
||||
* 如果在读取过程中发生异常, 将断开服务器连接并抛出 {@link ReadPointException}。
|
||||
*/
|
||||
private String readValue(Server server, DeviceBO deviceBO, SiteBO siteBO) {
|
||||
private String readValue(Server server, DeviceConnectionBO deviceConnectionBO, SiteBO siteBO) {
|
||||
try {
|
||||
Item item = getItem(server, deviceBO, siteBO);
|
||||
Item item = getItem(server, deviceConnectionBO, siteBO);
|
||||
return readItem(item);
|
||||
} catch (NotConnectedException | JIException | AddFailedException | DuplicateGroupException |
|
||||
UnknownHostException e) {
|
||||
@@ -142,13 +142,13 @@ public class OpcDaProtocolDriverImpl extends AbstractProtocolDriver<Server> {
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private List<RValue> batchReadValue(Server server, DeviceBO deviceBO, List<SiteBO> points) {
|
||||
private List<RValue> batchReadValue(Server server, DeviceConnectionBO deviceConnectionBO, List<SiteBO> points) {
|
||||
List<RValue> res = new ArrayList<>();
|
||||
Map<String, Item> itemsMap = getItems(server, deviceBO, points);
|
||||
Map<String, Item> itemsMap = getItems(server, deviceConnectionBO, points);
|
||||
for (Item item : itemsMap.values()) {
|
||||
RValue rValue = new RValue();
|
||||
rValue.setDeviceBO(deviceBO);
|
||||
SiteBO site = findSite(points, deviceBO, item.getId());
|
||||
rValue.setDeviceConnectionBO(deviceConnectionBO);
|
||||
SiteBO site = findSite(points, deviceConnectionBO, item.getId());
|
||||
rValue.setSiteBO(ObjectUtil.isNotEmpty(site) ? site : null);
|
||||
try {
|
||||
// 组装数据
|
||||
@@ -164,7 +164,7 @@ public class OpcDaProtocolDriverImpl extends AbstractProtocolDriver<Server> {
|
||||
return res;
|
||||
}
|
||||
|
||||
public List<WResponse> batchWriteValue(DeviceBO device, List<WValue> wValues) {
|
||||
public List<WResponse> batchWriteValue(DeviceConnectionBO device, List<WValue> wValues) {
|
||||
Server server = getConnector(device);
|
||||
List<WResponse> list = new ArrayList<>();
|
||||
for (WValue wValue : wValues) {
|
||||
@@ -185,35 +185,35 @@ public class OpcDaProtocolDriverImpl extends AbstractProtocolDriver<Server> {
|
||||
* 如果组不存在, 则创建新的组;如果组已存在, 则直接使用该组。
|
||||
*
|
||||
*/
|
||||
public Item getItem(Server server, DeviceBO deviceBO, SiteBO siteBO) throws NotConnectedException, JIException, UnknownHostException, DuplicateGroupException, AddFailedException {
|
||||
public Item getItem(Server server, DeviceConnectionBO deviceConnectionBO, SiteBO siteBO) throws NotConnectedException, JIException, UnknownHostException, DuplicateGroupException, AddFailedException {
|
||||
Group group;
|
||||
String groupName = deviceBO.getCode();
|
||||
String groupName = deviceConnectionBO.getCode();
|
||||
try {
|
||||
group = server.findGroup(groupName);
|
||||
} catch (UnknownGroupException e) {
|
||||
group = server.addGroup(groupName);
|
||||
}
|
||||
return group.addItem(groupName + "." + siteBO.getDeviceCode() + "." + siteBO.getAlias());
|
||||
return group.addItem(groupName + "." + groupName + "." + siteBO.getDeviceCode() + "." + siteBO.getAlias());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public Map<String, Item> getItems(Server server, DeviceBO deviceBO, List<SiteBO> points) {
|
||||
public Map<String, Item> getItems(Server server, DeviceConnectionBO deviceConnectionBO, List<SiteBO> points) {
|
||||
Group group;
|
||||
String groupName = deviceBO.getCode();
|
||||
String groupName = deviceConnectionBO.getCode();
|
||||
try {
|
||||
group = server.findGroup(groupName);
|
||||
} catch (UnknownGroupException e) {
|
||||
group = server.addGroup(groupName);
|
||||
}
|
||||
String[] arr = points.stream()
|
||||
.map(site -> groupName + "." + site.getDeviceCode() + "." + site.getAlias())
|
||||
.map(site -> groupName + "." + groupName + "." + site.getDeviceCode() + "." + site.getAlias())
|
||||
.toArray(String[]::new);
|
||||
return group.addItems(arr);
|
||||
}
|
||||
|
||||
public SiteBO findSite(List<SiteBO> points, DeviceBO deviceBO, String key) {
|
||||
public SiteBO findSite(List<SiteBO> points, DeviceConnectionBO deviceConnectionBO, String key) {
|
||||
for (SiteBO point : points) {
|
||||
String itemKey = deviceBO.getCode() + "." + point.getDeviceCode() + "." + point.getAlias();
|
||||
String itemKey = deviceConnectionBO.getCode() + "." + point.getDeviceCode() + "." + point.getAlias();
|
||||
if (itemKey.equals(key)) {
|
||||
return point;
|
||||
}
|
||||
@@ -249,9 +249,9 @@ public class OpcDaProtocolDriverImpl extends AbstractProtocolDriver<Server> {
|
||||
* @return boolean 返回写入操作是否成功
|
||||
* @throws WritePointException 如果写入位号值时发生异常, 则抛出此异常
|
||||
*/
|
||||
private Boolean writeValue(Server server, DeviceBO deviceBO, WValue wValue) {
|
||||
private Boolean writeValue(Server server, DeviceConnectionBO deviceConnectionBO, WValue wValue) {
|
||||
try {
|
||||
Item item = getItem(server, deviceBO, wValue.getPoint());
|
||||
Item item = getItem(server, deviceConnectionBO, wValue.getPoint());
|
||||
return writeItem(item, wValue);
|
||||
} catch (NotConnectedException | AddFailedException | DuplicateGroupException | UnknownHostException |
|
||||
JIException e) {
|
||||
|
||||
@@ -16,7 +16,7 @@ import org.nl.iot.core.driver.AbstractProtocolDriver;
|
||||
import org.nl.iot.core.driver.ConnectionProtocolMappingManager;
|
||||
import org.nl.iot.core.driver.ProtocolDriver;
|
||||
import org.nl.iot.core.driver.ProtocolType;
|
||||
import org.nl.iot.core.driver.bo.DeviceBO;
|
||||
import org.nl.iot.core.driver.bo.DeviceConnectionBO;
|
||||
import org.nl.iot.core.driver.bo.MetadataEventDTO;
|
||||
import org.nl.iot.core.driver.bo.SiteBO;
|
||||
import org.nl.iot.core.driver.entity.RValue;
|
||||
@@ -82,23 +82,23 @@ public class OpcUaProtocolDriverImpl extends AbstractProtocolDriver<OpcUaClient>
|
||||
}
|
||||
|
||||
@Override
|
||||
public RValue read(DeviceBO device, SiteBO point) {
|
||||
public RValue read(DeviceConnectionBO device, SiteBO point) {
|
||||
return readValue(device, point);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean write(DeviceBO device, WValue wValue) {
|
||||
public Boolean write(DeviceConnectionBO device, WValue wValue) {
|
||||
OpcUaClient client = getConnector(device);
|
||||
return writeValue(client, device, wValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RValue> batchRead(DeviceBO device, List<SiteBO> point) {
|
||||
public List<RValue> batchRead(DeviceConnectionBO device, List<SiteBO> point) {
|
||||
return batchReadValue(getConnector(device), device, point);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WResponse> batchWrite(DeviceBO device, List<WValue> wValue) {
|
||||
public List<WResponse> batchWrite(DeviceConnectionBO device, List<WValue> wValue) {
|
||||
int maxRetries = 2; // 最大重试次数
|
||||
|
||||
for (int retry = 0; retry <= maxRetries; retry++) {
|
||||
@@ -139,7 +139,7 @@ public class OpcUaProtocolDriverImpl extends AbstractProtocolDriver<OpcUaClient>
|
||||
/**
|
||||
* 获取 OPC UA 客户端连接
|
||||
*/
|
||||
private OpcUaClient getConnector(DeviceBO device) {
|
||||
private OpcUaClient getConnector(DeviceConnectionBO device) {
|
||||
log.debug("OPC UA server connection info: {}", device);
|
||||
OpcUaClient opcUaClient = connectMap.get(device.getId());
|
||||
|
||||
@@ -183,7 +183,7 @@ public class OpcUaProtocolDriverImpl extends AbstractProtocolDriver<OpcUaClient>
|
||||
* @param point 点位配置信息
|
||||
* @return 读取到的节点值
|
||||
*/
|
||||
private RValue readValue(DeviceBO device, SiteBO point) {
|
||||
private RValue readValue(DeviceConnectionBO device, SiteBO point) {
|
||||
int maxRetries = 2; // 最大重试次数
|
||||
|
||||
for (int retry = 0; retry <= maxRetries; retry++) {
|
||||
@@ -236,7 +236,7 @@ public class OpcUaProtocolDriverImpl extends AbstractProtocolDriver<OpcUaClient>
|
||||
* @param point
|
||||
* @return
|
||||
*/
|
||||
private List<RValue> batchReadValue(OpcUaClient connector, DeviceBO device, List<SiteBO> points) {
|
||||
private List<RValue> batchReadValue(OpcUaClient connector, DeviceConnectionBO device, List<SiteBO> points) {
|
||||
return batchReadNodes(connector, device, points);
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ public class OpcUaProtocolDriverImpl extends AbstractProtocolDriver<OpcUaClient>
|
||||
* @param points 点位列表
|
||||
* @return 读取结果列表(顺序与nodeIds一致)
|
||||
*/
|
||||
private List<RValue> batchReadNodes(OpcUaClient client, DeviceBO device, List<SiteBO> points) {
|
||||
private List<RValue> batchReadNodes(OpcUaClient client, DeviceConnectionBO device, List<SiteBO> points) {
|
||||
List<RValue> list = new ArrayList<>();
|
||||
int maxRetries = 2; // 最大重试次数
|
||||
|
||||
@@ -348,7 +348,7 @@ public class OpcUaProtocolDriverImpl extends AbstractProtocolDriver<OpcUaClient>
|
||||
/**
|
||||
* 写入 OPC UA 节点的值
|
||||
*/
|
||||
private boolean writeValue(OpcUaClient client, DeviceBO device, WValue wValue) {
|
||||
private boolean writeValue(OpcUaClient client, DeviceConnectionBO device, WValue wValue) {
|
||||
try {
|
||||
NodeId nodeId = NodeId.parse(wValue.getPoint().getRegisterAddress());
|
||||
// 确保客户端已连接,设置超时时间
|
||||
|
||||
@@ -14,7 +14,7 @@ import org.nl.iot.core.driver.AbstractProtocolDriver;
|
||||
import org.nl.iot.core.driver.ConnectionProtocolMappingManager;
|
||||
import org.nl.iot.core.driver.ProtocolDriver;
|
||||
import org.nl.iot.core.driver.ProtocolType;
|
||||
import org.nl.iot.core.driver.bo.DeviceBO;
|
||||
import org.nl.iot.core.driver.bo.DeviceConnectionBO;
|
||||
import org.nl.iot.core.driver.bo.MetadataEventDTO;
|
||||
import org.nl.iot.core.driver.bo.SiteBO;
|
||||
import org.nl.iot.core.driver.entity.RValue;
|
||||
@@ -76,7 +76,7 @@ public class PlcS7ProtocolDriverImpl extends AbstractProtocolDriver<PlcConnectio
|
||||
}
|
||||
|
||||
@Override
|
||||
public RValue read(DeviceBO device, SiteBO point) {
|
||||
public RValue read(DeviceConnectionBO device, SiteBO point) {
|
||||
try {
|
||||
log.debug("Plc S7 Read, connect: {}, config: {}", device, point);
|
||||
PlcConnection myS7Connector = getS7Connector(device);
|
||||
@@ -107,7 +107,7 @@ public class PlcS7ProtocolDriverImpl extends AbstractProtocolDriver<PlcConnectio
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RValue> batchRead(DeviceBO device, List<SiteBO> points) {
|
||||
public List<RValue> batchRead(DeviceConnectionBO device, List<SiteBO> points) {
|
||||
try {
|
||||
return batchReadValue(getS7Connector(device), device, points);
|
||||
} catch (Exception e) {
|
||||
@@ -121,21 +121,21 @@ public class PlcS7ProtocolDriverImpl extends AbstractProtocolDriver<PlcConnectio
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean write(DeviceBO device, WValue wValue) {
|
||||
public Boolean write(DeviceConnectionBO device, WValue wValue) {
|
||||
return writeValue(getS7Connector(device), device, wValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WResponse> batchWrite(DeviceBO device, List<WValue> wValue) {
|
||||
public List<WResponse> batchWrite(DeviceConnectionBO device, List<WValue> wValue) {
|
||||
return batchWriteValue(getS7Connector(device), wValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 PLC S7 连接器
|
||||
*/
|
||||
private PlcConnection getS7Connector(DeviceBO deviceBO) {
|
||||
private PlcConnection getS7Connector(DeviceConnectionBO deviceConnectionBO) {
|
||||
try {
|
||||
String deviceId = deviceBO.getId();
|
||||
String deviceId = deviceConnectionBO.getId();
|
||||
PlcConnection connection = connectMap.get(deviceId);
|
||||
|
||||
// 检查连接是否有效(核心修复:判断连接是否存在且未关闭)
|
||||
@@ -150,14 +150,14 @@ public class PlcS7ProtocolDriverImpl extends AbstractProtocolDriver<PlcConnectio
|
||||
connectMap.remove(deviceId);
|
||||
}
|
||||
// 创建新连接
|
||||
String connectionUrl = PlcS7Utils.getS7ConnectionUrl(deviceBO);
|
||||
String connectionUrl = PlcS7Utils.getS7ConnectionUrl(deviceConnectionBO);
|
||||
log.info("创建S7连接,deviceId: {}, url: {}", deviceId, connectionUrl);
|
||||
connection = new DefaultPlcDriverManager().getConnection(connectionUrl);
|
||||
addPlcS7Connection(deviceBO.getId(), connection);
|
||||
addPlcS7Connection(deviceConnectionBO.getId(), connection);
|
||||
}
|
||||
return connection;
|
||||
} catch (Exception e) {
|
||||
log.error("创建S7连接失败,deviceId: {}", deviceBO.getId(), e);
|
||||
log.error("创建S7连接失败,deviceId: {}", deviceConnectionBO.getId(), e);
|
||||
throw new CommonException("PLC S7 连接失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -211,11 +211,11 @@ public class PlcS7ProtocolDriverImpl extends AbstractProtocolDriver<PlcConnectio
|
||||
/**
|
||||
* 实现批量读取
|
||||
* @param s7Connection
|
||||
* @param deviceBO
|
||||
* @param deviceConnectionBO
|
||||
* @param points
|
||||
* @return
|
||||
*/
|
||||
public List<RValue> batchReadValue(PlcConnection s7Connection, DeviceBO deviceBO, List<SiteBO> points) {
|
||||
public List<RValue> batchReadValue(PlcConnection s7Connection, DeviceConnectionBO deviceConnectionBO, List<SiteBO> points) {
|
||||
List<RValue> list = new ArrayList<>();
|
||||
try {
|
||||
// 1. 解析配置
|
||||
@@ -231,17 +231,17 @@ public class PlcS7ProtocolDriverImpl extends AbstractProtocolDriver<PlcConnectio
|
||||
PlcResponseCode responseCode = readResponse.getResponseCode(point.getAlias());
|
||||
// 4. 校验响应码
|
||||
if (responseCode != PlcResponseCode.OK) {
|
||||
list.add(new RValue(deviceBO, point, null, String.format(
|
||||
list.add(new RValue(deviceConnectionBO, point, null, String.format(
|
||||
"读取S7失败,设备编码:%s,地址:%s,响应码:%s", point.getAlias(), point.getRegisterAddress(), responseCode
|
||||
)));
|
||||
continue;
|
||||
}
|
||||
// 5. 取值并转换
|
||||
PlcValue plcValue = readResponse.getPlcValue(point.getAlias());
|
||||
list.add(new RValue(deviceBO, point, PlcValueConvertUtil.convertPlcValueToString(plcValue, point.getDataType()), null));
|
||||
list.add(new RValue(deviceConnectionBO, point, PlcValueConvertUtil.convertPlcValueToString(plcValue, point.getDataType()), null));
|
||||
} catch (Exception e) {
|
||||
log.error("处理单个点位数据异常,设备编码:{},地址:{}", point.getAlias(), point.getRegisterAddress(), e);
|
||||
list.add(new RValue(deviceBO, point, null, String.format(
|
||||
list.add(new RValue(deviceConnectionBO, point, null, String.format(
|
||||
"读取S7失败,设备编码:%s,地址:%s,异常信息:%s", point.getAlias(), point.getRegisterAddress(), e.getMessage()
|
||||
)));
|
||||
}
|
||||
@@ -250,7 +250,7 @@ public class PlcS7ProtocolDriverImpl extends AbstractProtocolDriver<PlcConnectio
|
||||
log.error("批量读取S7数据异常", e);
|
||||
// 如果整个批量读取失败,为所有点位返回异常信息
|
||||
for (SiteBO point : points) {
|
||||
list.add(new RValue(deviceBO, point, null, String.format(
|
||||
list.add(new RValue(deviceConnectionBO, point, null, String.format(
|
||||
"批量读取S7失败,设备编码:%s,地址:%s,异常信息:%s", point.getAlias(), point.getRegisterAddress(), e.getMessage()
|
||||
)));
|
||||
}
|
||||
@@ -258,7 +258,7 @@ public class PlcS7ProtocolDriverImpl extends AbstractProtocolDriver<PlcConnectio
|
||||
return list;
|
||||
}
|
||||
|
||||
private boolean writeValue(PlcConnection modbusMaster, DeviceBO deviceBO, WValue wValue) {
|
||||
private boolean writeValue(PlcConnection modbusMaster, DeviceConnectionBO deviceConnectionBO, WValue wValue) {
|
||||
// 1. 解析配置
|
||||
PlcWriteRequest.Builder writeRequestBuilder = doBuildWriteRequest(modbusMaster, Collections.singletonList(wValue));
|
||||
PlcWriteRequest writeRequest = writeRequestBuilder.build();
|
||||
|
||||
@@ -2,7 +2,7 @@ package org.nl.iot.core.driver.protocol.plcs7.util;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.nl.iot.core.driver.bo.DeviceBO;
|
||||
import org.nl.iot.core.driver.bo.DeviceConnectionBO;
|
||||
|
||||
/**
|
||||
* plc s7 工具类
|
||||
@@ -12,16 +12,16 @@ import org.nl.iot.core.driver.bo.DeviceBO;
|
||||
public class PlcS7Utils {
|
||||
public static final String S7_CONN_PRX = "s7://";
|
||||
|
||||
public static String getS7ConnectionUrl(DeviceBO deviceBO) {
|
||||
public static String getS7ConnectionUrl(DeviceConnectionBO deviceConnectionBO) {
|
||||
// 包含:remote-rack、remote-slot、controller-type
|
||||
JSONObject propertiesMap = JSONObject.parseObject(deviceBO.getProperties());
|
||||
JSONObject propertiesMap = JSONObject.parseObject(deviceConnectionBO.getProperties());
|
||||
|
||||
// 获取设备IP地址
|
||||
String ip = deviceBO.getHost();
|
||||
String ip = deviceConnectionBO.getHost();
|
||||
if (ip == null || ip.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("设备IP地址不能为空");
|
||||
}
|
||||
String port = deviceBO.getPort().toString();
|
||||
String port = deviceConnectionBO.getPort().toString();
|
||||
if (ObjectUtil.isEmpty(port.trim().isEmpty()) || port.equals("null")) {
|
||||
port = "102";
|
||||
}
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
package org.nl.iot.core.driver.service;
|
||||
|
||||
import org.nl.iot.core.driver.bo.AttributeBO;
|
||||
import org.nl.iot.core.driver.bo.DeviceBO;
|
||||
import org.nl.iot.core.driver.bo.DeviceConnectionBO;
|
||||
import org.nl.iot.core.driver.bo.MetadataEventDTO;
|
||||
import org.nl.iot.core.driver.bo.SiteBO;
|
||||
import org.nl.iot.core.driver.entity.RValue;
|
||||
import org.nl.iot.core.driver.entity.WResponse;
|
||||
import org.nl.iot.core.driver.entity.WValue;
|
||||
import org.nl.iot.modular.iot.entity.IotConfig;
|
||||
import org.nl.iot.modular.iot.entity.IotConnect;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 自定义通信协议驱动服务
|
||||
@@ -42,7 +38,7 @@ public interface DriverCustomService {
|
||||
/**
|
||||
* 执行读操作
|
||||
*/
|
||||
RValue read(DeviceBO device, SiteBO point);
|
||||
RValue read(DeviceConnectionBO device, SiteBO point);
|
||||
|
||||
/**
|
||||
* 批量读取
|
||||
@@ -50,12 +46,12 @@ public interface DriverCustomService {
|
||||
* @param point
|
||||
* @return
|
||||
*/
|
||||
List<RValue> batchRead(DeviceBO device, List<SiteBO> point);
|
||||
List<RValue> batchRead(DeviceConnectionBO device, List<SiteBO> point);
|
||||
|
||||
/**
|
||||
* 执行写操作
|
||||
*/
|
||||
Boolean write(DeviceBO device, WValue wValue);
|
||||
Boolean write(DeviceConnectionBO device, WValue wValue);
|
||||
|
||||
/**
|
||||
* 批量写
|
||||
@@ -63,6 +59,6 @@ public interface DriverCustomService {
|
||||
* @param wValue
|
||||
* @return
|
||||
*/
|
||||
List<WResponse> batchWrite(DeviceBO device, List<WValue> wValue);
|
||||
List<WResponse> batchWrite(DeviceConnectionBO device, List<WValue> wValue);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.nl.iot.core.schedule;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nl.common.timer.CommonTimerTaskRunner;
|
||||
import org.nl.iot.core.cache.MetadataCacheManager;
|
||||
import org.nl.iot.core.driver.DriverCustomFactory;
|
||||
import org.nl.iot.core.driver.bo.DeviceConnectionBO;
|
||||
import org.nl.iot.core.driver.bo.DeviceInfoReadCacheDo;
|
||||
import org.nl.iot.core.driver.bo.SiteBO;
|
||||
import org.nl.iot.core.driver.entity.RValue;
|
||||
import org.nl.iot.core.driver.service.DriverCustomService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 定时器
|
||||
* <p>定时读取设备数据
|
||||
* <p>组装的数据:连接编码.设备编码.信号编码 -> 对应的值(已经String化)
|
||||
* @Author: liyongde
|
||||
* @Date: 2026/3/20 16:14
|
||||
* @Modified By:
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AutoReadAllSignalTaskRunner implements CommonTimerTaskRunner {
|
||||
@Autowired
|
||||
private MetadataCacheManager metadataCacheManager;
|
||||
@Autowired
|
||||
private DriverCustomFactory driverCustomFactory;
|
||||
|
||||
@Override
|
||||
public void action(String extJson) {
|
||||
Map<String, DeviceInfoReadCacheDo> allDeviceInfoCache = metadataCacheManager.getAllDeviceInfoCache();
|
||||
if (allDeviceInfoCache.isEmpty()) {
|
||||
log.error("设备缓存为空...");
|
||||
return;
|
||||
}
|
||||
// 读取
|
||||
for (Map.Entry<String, DeviceInfoReadCacheDo> entry : allDeviceInfoCache.entrySet()) {
|
||||
// 获取Map的Key(这里Key是设备ID,和实体中的deviceId可能相同/不同)
|
||||
String key = entry.getKey();
|
||||
// 获取Map的Value(设备信息对象)
|
||||
DeviceInfoReadCacheDo deviceInfo = entry.getValue();
|
||||
DeviceConnectionBO deviceConnectionBO = deviceInfo.getDeviceConnectionBO();
|
||||
List<SiteBO> siteBOS = deviceInfo.getSiteBOS();
|
||||
DriverCustomService driver = driverCustomFactory.getDriver(deviceConnectionBO.getProtocol());
|
||||
List<RValue> list = driver.batchRead(deviceConnectionBO, siteBOS);
|
||||
// 组装数据
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,16 @@ package org.nl.iot.modular.iot.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.nl.iot.core.driver.bo.ConnectSiteDO;
|
||||
import org.nl.iot.modular.iot.entity.IotConfig;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 信号配置表Mapper
|
||||
*/
|
||||
@Mapper
|
||||
public interface IotConfigMapper extends BaseMapper<IotConfig> {
|
||||
|
||||
List<ConnectSiteDO> getAllDeviceInfo();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.nl.iot.modular.iot.mapper.IotConfigMapper">
|
||||
|
||||
<select id="getAllDeviceInfo" resultType="org.nl.iot.core.driver.bo.ConnectSiteDO">
|
||||
SELECT
|
||||
ic.connect_id,
|
||||
ict.code AS connect_code,
|
||||
ict.host,
|
||||
ict.port,
|
||||
ict.properties,
|
||||
ict.protocol,
|
||||
ict.collect_mode,
|
||||
id.code AS device_code,
|
||||
ic.alias,
|
||||
ic.register_address,
|
||||
ic.alias_name,
|
||||
ic.data_type,
|
||||
ic.readonly
|
||||
FROM
|
||||
`iot_config` ic
|
||||
LEFT JOIN iot_device id ON id.id = ic.sub_device_id
|
||||
LEFT JOIN iot_connect ict ON ict.id = ic.connect_id
|
||||
WHERE ic.enabled = TRUE
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -3,9 +3,12 @@ package org.nl.iot.modular.iot.service;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.nl.iot.core.driver.bo.ConnectSiteDO;
|
||||
import org.nl.iot.modular.iot.entity.IotConfig;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 信号配置表Service接口
|
||||
*/
|
||||
@@ -20,4 +23,10 @@ public interface IotConfigService extends IService<IotConfig> {
|
||||
* 导入信号配置
|
||||
*/
|
||||
JSONObject importConfig(MultipartFile file);
|
||||
|
||||
/**
|
||||
* 获取所有的设备+连接+配置的关联数据
|
||||
* @return
|
||||
*/
|
||||
List<ConnectSiteDO> getAllDeviceInfo();
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
package org.nl.iot.modular.iot.service.impl;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.nl.common.exception.CommonException;
|
||||
import org.nl.common.util.CommonDownloadUtil;
|
||||
import org.nl.common.util.CommonResponseUtil;
|
||||
import org.nl.iot.core.driver.bo.ConnectSiteDO;
|
||||
import org.nl.iot.modular.iot.entity.IotConfig;
|
||||
import org.nl.iot.modular.iot.mapper.IotConfigMapper;
|
||||
import org.nl.iot.modular.iot.param.IotConfigImportParam;
|
||||
@@ -74,6 +75,11 @@ public class IotConfigServiceImpl extends ServiceImpl<IotConfigMapper, IotConfig
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ConnectSiteDO> getAllDeviceInfo() {
|
||||
return this.baseMapper.getAllDeviceInfo();
|
||||
}
|
||||
|
||||
private JSONObject doImport(IotConfigImportParam param, int index) {
|
||||
if (ObjectUtil.hasEmpty(param.getConnectId(), param.getSubDeviceId(), param.getAlias(),
|
||||
param.getRegisterAddress(), param.getAliasName(), param.getDataType())) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import org.junit.runner.RunWith;
|
||||
import org.nl.common.exception.CommonException;
|
||||
import org.nl.iot.core.driver.DriverCustomFactory;
|
||||
import org.nl.iot.core.driver.ProtocolType;
|
||||
import org.nl.iot.core.driver.bo.DeviceBO;
|
||||
import org.nl.iot.core.driver.bo.DeviceConnectionBO;
|
||||
import org.nl.iot.core.driver.bo.SiteBO;
|
||||
import org.nl.iot.core.driver.entity.RValue;
|
||||
import org.nl.iot.core.driver.entity.WResponse;
|
||||
@@ -23,7 +23,6 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -84,7 +83,7 @@ public class ApiTest {
|
||||
System.out.println("数据类型: " + config.getDataType());
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
@@ -104,7 +103,7 @@ public class ApiTest {
|
||||
.build();
|
||||
|
||||
// 调用驱动读取数据
|
||||
RValue result = modBusProtocolDriver.read(deviceBO, siteBO);
|
||||
RValue result = modBusProtocolDriver.read(deviceConnectionBO, siteBO);
|
||||
|
||||
System.out.println("读取成功!");
|
||||
System.out.println("读取结果: " + result.getValue());
|
||||
@@ -153,7 +152,7 @@ public class ApiTest {
|
||||
System.out.println("数据类型: " + config.getDataType());
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
@@ -183,7 +182,7 @@ public class ApiTest {
|
||||
System.out.println("写入值: " + writeValue);
|
||||
|
||||
// 调用驱动写入数据
|
||||
Boolean result = modBusProtocolDriver.write(deviceBO, wValue);
|
||||
Boolean result = modBusProtocolDriver.write(deviceConnectionBO, wValue);
|
||||
|
||||
if (result != null && result) {
|
||||
System.out.println("写入成功!");
|
||||
@@ -269,7 +268,7 @@ public class ApiTest {
|
||||
System.out.println("连接信息: " + connect.getHost() + ":" + connect.getPort());
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
@@ -321,7 +320,7 @@ public class ApiTest {
|
||||
}
|
||||
|
||||
// 调用驱动批量读取数据
|
||||
List<RValue> result = modBusProtocolDriver.batchRead(deviceBO, siteBOList);
|
||||
List<RValue> result = modBusProtocolDriver.batchRead(deviceConnectionBO, siteBOList);
|
||||
|
||||
System.out.println("批量读取成功!");
|
||||
System.out.println("读取结果:");
|
||||
@@ -401,7 +400,7 @@ public class ApiTest {
|
||||
System.out.println("连接信息: " + connect.getHost() + ":" + connect.getPort());
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
@@ -458,7 +457,7 @@ public class ApiTest {
|
||||
}
|
||||
|
||||
// 调用驱动批量写入数据
|
||||
List<WResponse> result = modBusProtocolDriver.batchWrite(deviceBO, wValueList);
|
||||
List<WResponse> result = modBusProtocolDriver.batchWrite(deviceConnectionBO, wValueList);
|
||||
|
||||
System.out.println("批量写入完成!");
|
||||
System.out.println("写入结果:");
|
||||
@@ -547,7 +546,7 @@ public class ApiTest {
|
||||
System.out.println("插槽号: " + properties.getString("remote-slot"));
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
@@ -583,7 +582,7 @@ public class ApiTest {
|
||||
.readonly(config2.getReadonly())
|
||||
.build();
|
||||
|
||||
RValue result2 = plcS7ProtocolDriver.read(deviceBO, siteBO2);
|
||||
RValue result2 = plcS7ProtocolDriver.read(deviceConnectionBO, siteBO2);
|
||||
System.out.println("地址: " + config2.getRegisterAddress());
|
||||
System.out.println("数据类型: " + config2.getDataType());
|
||||
System.out.println("读取结果: " + result2.getValue());
|
||||
@@ -677,7 +676,7 @@ public class ApiTest {
|
||||
System.out.println("控制器类型: " + properties.getString("controller-type"));
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
@@ -721,7 +720,7 @@ public class ApiTest {
|
||||
}
|
||||
|
||||
// 调用驱动批量读取数据
|
||||
List<RValue> result = plcS7ProtocolDriver.batchRead(deviceBO, siteBOList);
|
||||
List<RValue> result = plcS7ProtocolDriver.batchRead(deviceConnectionBO, siteBOList);
|
||||
|
||||
System.out.println("批量读取完成!");
|
||||
System.out.println("读取结果:");
|
||||
@@ -783,7 +782,7 @@ public class ApiTest {
|
||||
System.out.println("数据类型: " + config.getDataType());
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
@@ -813,7 +812,7 @@ public class ApiTest {
|
||||
System.out.println("写入值: " + writeValue);
|
||||
|
||||
// 调用驱动写入数据
|
||||
Boolean result = plcS7ProtocolDriver.write(deviceBO, wValue);
|
||||
Boolean result = plcS7ProtocolDriver.write(deviceConnectionBO, wValue);
|
||||
|
||||
if (result != null && result) {
|
||||
System.out.println("写入成功!");
|
||||
@@ -892,7 +891,7 @@ public class ApiTest {
|
||||
System.out.println("控制器类型: " + properties.getString("controller-type"));
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
@@ -949,7 +948,7 @@ public class ApiTest {
|
||||
}
|
||||
|
||||
// 调用驱动批量写入数据
|
||||
List<WResponse> result = plcS7ProtocolDriver.batchWrite(deviceBO, wValueList);
|
||||
List<WResponse> result = plcS7ProtocolDriver.batchWrite(deviceConnectionBO, wValueList);
|
||||
|
||||
System.out.println("批量写入完成!");
|
||||
System.out.println("写入结果:");
|
||||
@@ -1032,7 +1031,7 @@ public class ApiTest {
|
||||
System.out.println("服务器路径: " + properties.getString("path"));
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
@@ -1071,7 +1070,7 @@ public class ApiTest {
|
||||
.readonly(config2.getReadonly())
|
||||
.build();
|
||||
|
||||
RValue result2 = opcUaProtocolDriver.read(deviceBO, siteBO2);
|
||||
RValue result2 = opcUaProtocolDriver.read(deviceConnectionBO, siteBO2);
|
||||
System.out.println("节点ID: " + config2.getRegisterAddress());
|
||||
System.out.println("数据类型: " + config2.getDataType());
|
||||
System.out.println("读取结果: " + result2.getValue());
|
||||
@@ -1180,7 +1179,7 @@ public class ApiTest {
|
||||
System.out.println("服务器路径: " + properties.getString("path"));
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
@@ -1232,7 +1231,7 @@ public class ApiTest {
|
||||
}
|
||||
|
||||
// 调用驱动批量读取数据
|
||||
List<RValue> result = opcUaProtocolDriver.batchRead(deviceBO, siteBOList);
|
||||
List<RValue> result = opcUaProtocolDriver.batchRead(deviceConnectionBO, siteBOList);
|
||||
|
||||
System.out.println("批量读取完成!");
|
||||
System.out.println("读取结果:");
|
||||
@@ -1293,7 +1292,7 @@ public class ApiTest {
|
||||
System.out.println("数据类型: " + config.getDataType());
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
@@ -1323,7 +1322,7 @@ public class ApiTest {
|
||||
System.out.println("写入值: " + writeValue);
|
||||
|
||||
// 调用驱动写入数据
|
||||
Boolean result = opcUaProtocolDriver.write(deviceBO, wValue);
|
||||
Boolean result = opcUaProtocolDriver.write(deviceConnectionBO, wValue);
|
||||
|
||||
if (result != null && result) {
|
||||
System.out.println("写入成功!");
|
||||
@@ -1400,7 +1399,7 @@ public class ApiTest {
|
||||
System.out.println("服务器路径: " + properties.getString("path"));
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
@@ -1457,7 +1456,7 @@ public class ApiTest {
|
||||
}
|
||||
|
||||
// 调用驱动批量写入数据
|
||||
List<WResponse> result = opcUaProtocolDriver.batchWrite(deviceBO, wValueList);
|
||||
List<WResponse> result = opcUaProtocolDriver.batchWrite(deviceConnectionBO, wValueList);
|
||||
|
||||
System.out.println("批量写入完成!");
|
||||
System.out.println("写入结果:");
|
||||
@@ -1529,7 +1528,7 @@ public class ApiTest {
|
||||
System.out.println("数据类型: " + config.getDataType());
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
@@ -1549,7 +1548,7 @@ public class ApiTest {
|
||||
.build();
|
||||
|
||||
// 调用驱动读取数据
|
||||
RValue result = opcDaProtocolDriver.read(deviceBO, siteBO);
|
||||
RValue result = opcDaProtocolDriver.read(deviceConnectionBO, siteBO);
|
||||
|
||||
System.out.println("读取成功!");
|
||||
System.out.println("读取结果: " + result.getValue());
|
||||
@@ -1608,7 +1607,7 @@ public class ApiTest {
|
||||
System.out.println("数据类型: " + config.getDataType());
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
@@ -1638,7 +1637,7 @@ public class ApiTest {
|
||||
System.out.println("写入值: " + writeValue);
|
||||
|
||||
// 调用驱动写入数据
|
||||
Boolean result = opcDaProtocolDriver.write(deviceBO, wValue);
|
||||
Boolean result = opcDaProtocolDriver.write(deviceConnectionBO, wValue);
|
||||
|
||||
if (result != null && result) {
|
||||
System.out.println("写入成功!");
|
||||
@@ -1730,7 +1729,7 @@ public class ApiTest {
|
||||
System.out.println("用户名: " + properties.getString("username"));
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
@@ -1782,7 +1781,7 @@ public class ApiTest {
|
||||
}
|
||||
|
||||
// 调用驱动批量读取数据
|
||||
List<RValue> result = opcDaProtocolDriver.batchRead(deviceBO, siteBOList);
|
||||
List<RValue> result = opcDaProtocolDriver.batchRead(deviceConnectionBO, siteBOList);
|
||||
|
||||
System.out.println("批量读取完成!");
|
||||
System.out.println("读取结果:");
|
||||
@@ -1885,7 +1884,7 @@ public class ApiTest {
|
||||
System.out.println("用户名: " + properties.getString("username"));
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
DeviceConnectionBO deviceConnectionBO = DeviceConnectionBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
@@ -1942,7 +1941,7 @@ public class ApiTest {
|
||||
}
|
||||
|
||||
// 调用驱动批量写入数据
|
||||
List<WResponse> result = opcDaProtocolDriver.batchWrite(deviceBO, wValueList);
|
||||
List<WResponse> result = opcDaProtocolDriver.batchWrite(deviceConnectionBO, wValueList);
|
||||
|
||||
System.out.println("批量写入完成!");
|
||||
System.out.println("写入结果:");
|
||||
|
||||
Reference in New Issue
Block a user