更新2级写入,以及前端处理

This commit is contained in:
2026-04-13 15:06:32 +08:00
parent a128bf7905
commit 80032fa758
4 changed files with 124 additions and 20 deletions

View File

@@ -0,0 +1,48 @@
package com.fizz.business.comm.iot;
import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import java.util.Locale;
/**
* 基于 iot-communication 的 S7 写入客户端(仅用于写入)。
*/
@Slf4j
@Component
@ConditionalOnProperty(prefix = "iot.communication", name = "enabled", havingValue = "true")
public class S7WriteClient {
@Value("${iot.communication.s7.ip:127.0.0.1}")
private String ip;
@Value("${iot.communication.s7.port:102}")
private int port;
@Value("${iot.communication.s7.rack:0}")
private int rack;
@Value("${iot.communication.s7.slot:1}")
private int slot;
@Value("${iot.communication.s7.plc-type:S1200}")
private String plcType;
public S7PLC newClient() {
EPlcType type = parsePlcType(plcType);
return new S7PLC(type, ip, port, rack, slot);
}
private EPlcType parsePlcType(String value) {
try {
return EPlcType.valueOf(value.trim().toUpperCase(Locale.ROOT));
} catch (Exception e) {
log.warn("未知 plc-type: {},回退到 S1200", value);
return EPlcType.S1200;
}
}
}

View File

@@ -22,7 +22,7 @@ import javax.validation.Valid;
@RequiredArgsConstructor
@RequestMapping("/api/opc/data")
@Tag(name = "OPC 数据读写")
@ConditionalOnProperty(prefix = "kangaroohy.milo", name = "enabled", havingValue = "true")
@ConditionalOnProperty(prefix = "iot.communication", name = "enabled", havingValue = "true")
@Anonymous
public class OpcDataController {

View File

@@ -1,52 +1,96 @@
package com.fizz.business.service.impl;
import com.fizz.business.comm.OPC.OpcMessageSend;
import com.fizz.business.comm.iot.S7WriteClient;
import com.fizz.business.form.OpcBatchWriteDataForm;
import com.fizz.business.form.OpcWriteDataForm;
import com.fizz.business.service.OpcDataService;
import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.stream.Collectors;
/**
* OPC 数据读写服务实现类
*
* 说明:
* 1) 写入逻辑已切换为 iot-communicationS7
* 2) 读取逻辑仍保留在原 OPC 体系(不在本类中)
*/
@Slf4j
@Service
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = "kangaroohy.milo", name = "enabled", havingValue = "true")
@ConditionalOnProperty(prefix = "iot.communication", name = "enabled", havingValue = "true")
public class OpcDataServiceImpl implements OpcDataService {
private final OpcMessageSend opcMessageSend;
private final S7WriteClient s7WriteClient;
@Override
public boolean writeData(OpcWriteDataForm form) {
try {
return opcMessageSend.writeDataByFieldName(form.getFieldName(), form.getValue());
try (S7PLC s7PLC = s7WriteClient.newClient()) {
writeByGuessType(s7PLC, form.getFieldName(), form.getValue());
return true;
} catch (Exception e) {
log.error("写入 OPC 数据异常,fieldName={}, value={}", form.getFieldName(), form.getValue(), e);
log.error("写入 S7 数据异常,address={}, value={}", form.getFieldName(), form.getValue(), e);
return false;
}
}
@Override
public boolean batchWriteData(OpcBatchWriteDataForm form) {
try {
Map<String, Object> fieldDataMap = form.getDataList().stream()
.collect(Collectors.toMap(
OpcWriteDataForm::getFieldName,
OpcWriteDataForm::getValue,
(v1, v2) -> v2 // 如果有重复的 key保留后面的值
));
return opcMessageSend.batchWriteDataByFieldName(fieldDataMap);
try (S7PLC s7PLC = s7WriteClient.newClient()) {
for (OpcWriteDataForm item : form.getDataList()) {
writeByGuessType(s7PLC, item.getFieldName(), item.getValue());
}
return true;
} catch (Exception e) {
log.error("批量写入 OPC 数据异常", e);
log.error("批量写入 S7 数据异常", e);
return false;
}
}
}
private void writeByGuessType(S7PLC s7PLC, String address, Object value) {
if (value == null) {
throw new IllegalArgumentException("写入值不能为空");
}
if (address == null || address.trim().isEmpty()) {
throw new IllegalArgumentException("写入地址不能为空");
}
if (value instanceof Boolean) {
s7PLC.writeBoolean(address, (Boolean) value);
return;
}
if (value instanceof Byte) {
s7PLC.writeByte(address, (Byte) value);
return;
}
if (value instanceof Short) {
s7PLC.writeInt16(address, (Short) value);
return;
}
if (value instanceof Integer) {
s7PLC.writeInt32(address, (Integer) value);
return;
}
if (value instanceof Long) {
s7PLC.writeInt64(address, (Long) value);
return;
}
if (value instanceof Float) {
s7PLC.writeFloat32(address, (Float) value);
return;
}
if (value instanceof Double) {
s7PLC.writeFloat64(address, (Double) value);
return;
}
if (value instanceof byte[]) {
s7PLC.writeByte(address, (byte[]) value);
return;
}
// 兜底按字符串写入
s7PLC.writeString(address, String.valueOf(value));
}
}

View File

@@ -181,6 +181,18 @@ kangaroohy:
min-idle: 2
initial-size: 3
# iot-communicationS7写入开关与连接参数
# 注意:写入使用 iot-communication读取逻辑仍沿用 OPC 现有体系
iot:
communication:
enabled: true
s7:
ip: 127.0.0.1
port: 102
rack: 0
slot: 1
plc-type: S1200
#kangaroohy:
# milo: