package com.mes.plc.client.impl;
|
|
import com.mes.connect.modbus.ModbusTcpClient;
|
import com.mes.device.entity.DeviceConfig;
|
import com.mes.plc.client.PlcClient;
|
import lombok.extern.slf4j.Slf4j;
|
|
import java.util.Collections;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
/**
|
* Modbus协议PLC客户端实现
|
* <p>
|
* 基于项目中已有的Modbus实现
|
* </p>
|
*
|
* @author huang
|
* @date 2025/12/19
|
*/
|
@Slf4j
|
public class ModbusPlcClient implements PlcClient {
|
|
// PLC IP地址
|
private final String plcIp;
|
|
// PLC端口
|
private final int plcPort;
|
|
// 从站地址
|
private final int unitId;
|
|
// Modbus客户端实例
|
private ModbusTcpClient modbusClient;
|
|
// 连接状态
|
private boolean connected = false;
|
|
// 超时时间(毫秒)
|
private int timeout = 5000;
|
|
/**
|
* 构造函数
|
*
|
* @param device 设备配置
|
*/
|
public ModbusPlcClient(DeviceConfig device) {
|
this.plcIp = device.getPlcIp();
|
this.plcPort = device.getPlcPort() != null ? device.getPlcPort() : 502;
|
|
// 从配置中获取从站地址,默认1
|
int unitIdValue = 1;
|
try {
|
Map<String, Object> extraParams = parseExtraParams(device.getExtraParams());
|
if (extraParams != null) {
|
Object unitIdObj = extraParams.get("unitId");
|
if (unitIdObj instanceof Number) {
|
unitIdValue = ((Number) unitIdObj).intValue();
|
} else if (unitIdObj instanceof String) {
|
unitIdValue = Integer.parseInt((String) unitIdObj);
|
}
|
}
|
} catch (Exception e) {
|
log.warn("解析unitId失败,使用默认值1: deviceId={}", device.getId(), e);
|
}
|
this.unitId = unitIdValue;
|
}
|
|
/**
|
* 解析设备的extraParams
|
*
|
* @param extraParamsJson extraParams的JSON字符串
|
* @return 解析后的Map
|
*/
|
private Map<String, Object> parseExtraParams(String extraParamsJson) {
|
if (extraParamsJson == null || extraParamsJson.isEmpty()) {
|
return null;
|
}
|
|
try {
|
// 这里简化处理,实际项目中应该使用Jackson或Gson解析
|
// 由于项目中已有ObjectMapper,这里暂时返回空Map,后续完善
|
return new HashMap<>();
|
} catch (Exception e) {
|
log.error("解析extraParams失败: {}", extraParamsJson, e);
|
return null;
|
}
|
}
|
|
@Override
|
public boolean connect() {
|
try {
|
if (modbusClient != null && isConnected()) {
|
return true;
|
}
|
|
// 创建Modbus客户端实例
|
this.modbusClient = new ModbusTcpClient(this.plcIp, this.plcPort, this.unitId);
|
|
// 连接PLC
|
this.modbusClient.connect();
|
this.connected = true;
|
log.info("Modbus PLC连接成功: {}:{},从站地址: {}", this.plcIp, this.plcPort, this.unitId);
|
return true;
|
} catch (Exception e) {
|
log.error("Modbus PLC连接失败: {}:{}", this.plcIp, this.plcPort, e);
|
this.connected = false;
|
return false;
|
}
|
}
|
|
@Override
|
public void disconnect() {
|
try {
|
if (this.modbusClient != null) {
|
this.modbusClient.disconnect();
|
log.info("Modbus PLC断开连接: {}:{}", this.plcIp, this.plcPort);
|
}
|
} catch (Exception e) {
|
log.error("Modbus PLC断开连接失败: {}:{}", this.plcIp, this.plcPort, e);
|
} finally {
|
this.connected = false;
|
this.modbusClient = null;
|
}
|
}
|
|
@Override
|
public Map<String, Object> readAllData() {
|
if (!isConnected() && !connect()) {
|
log.error("Modbus PLC未连接,无法读取数据: {}:{}", this.plcIp, this.plcPort);
|
return Collections.emptyMap();
|
}
|
|
try {
|
// TODO: 实现Modbus读取所有数据
|
// 这里暂时返回空Map,后续完善
|
log.warn("Modbus readAllData未实现,返回空Map");
|
return new HashMap<>();
|
} catch (Exception e) {
|
log.error("Modbus PLC读取所有数据失败: {}:{}", this.plcIp, this.plcPort, e);
|
this.connected = false;
|
return Collections.emptyMap();
|
}
|
}
|
|
@Override
|
public Map<String, Object> readData(String... fields) {
|
if (!isConnected() && !connect()) {
|
log.error("Modbus PLC未连接,无法读取数据: {}:{}", this.plcIp, this.plcPort);
|
return Collections.emptyMap();
|
}
|
|
try {
|
// TODO: 实现Modbus读取指定字段数据
|
// 这里暂时返回空Map,后续完善
|
log.warn("Modbus readData未实现,返回空Map");
|
return new HashMap<>();
|
} catch (Exception e) {
|
log.error("Modbus PLC读取数据失败: {}:{}", this.plcIp, this.plcPort, e);
|
this.connected = false;
|
return Collections.emptyMap();
|
}
|
}
|
|
@Override
|
public boolean writeData(Map<String, Object> data) {
|
if (!isConnected() && !connect()) {
|
log.error("Modbus PLC未连接,无法写入数据: {}:{}", this.plcIp, this.plcPort);
|
return false;
|
}
|
|
try {
|
// TODO: 实现Modbus写入数据
|
// 这里暂时返回true,后续完善
|
log.warn("Modbus writeData未实现,返回成功");
|
return true;
|
} catch (Exception e) {
|
log.error("Modbus PLC写入数据失败: {}:{}", this.plcIp, this.plcPort, e);
|
this.connected = false;
|
return false;
|
}
|
}
|
|
@Override
|
public boolean isConnected() {
|
try {
|
if (!this.connected || this.modbusClient == null) {
|
return false;
|
}
|
// 检查连接状态
|
return this.modbusClient.isConnected();
|
} catch (Exception e) {
|
this.connected = false;
|
return false;
|
}
|
}
|
|
@Override
|
public String getPlcType() {
|
return "MODBUS";
|
}
|
|
@Override
|
public int getTimeout() {
|
return this.timeout;
|
}
|
|
@Override
|
public void setTimeout(int timeout) {
|
this.timeout = timeout;
|
// ModbusTcpClient不支持直接设置超时,这里仅记录超时时间
|
}
|
}
|