feat: 增加iec104底层组件

haikang
huangfeng 8 months ago
parent 7bc95e6e6a
commit 2a3e2902cb

@ -193,6 +193,11 @@
<artifactId>asn1bean</artifactId>
<version>1.14.0</version>
</dependency>
<dependency>
<groupId>org.openmuc</groupId>
<artifactId>j60870</artifactId>
<version>1.7.2</version>
</dependency>
</dependencies>
<build>

@ -0,0 +1,53 @@
package com.xydl.cac.iec104;
import lombok.extern.slf4j.Slf4j;
import org.openmuc.j60870.*;
import org.openmuc.j60870.ie.IeQualifierOfInterrogation;
import java.io.IOException;
import java.net.InetAddress;
@Slf4j
public class Iec104Client implements ConnectionEventListener {
public String ip;
public Integer port;
Connection connection;
public void connect(String _ip, Integer _port) throws Exception {
ip = _ip;
port = _port;
InetAddress address = InetAddress.getByName(ip);
ClientConnectionBuilder clientConnectionBuilder = new ClientConnectionBuilder(address)
.setMessageFragmentTimeout(5_000)
.setConnectionTimeout(20_000)
.setPort(port)
.setConnectionEventListener(this);
connection = clientConnectionBuilder.build();
}
public void disconnect() {
if (connection != null) {
connection.close();
}
}
public void interrogation() throws Exception {
connection.interrogation(1, CauseOfTransmission.ACTIVATION,
new IeQualifierOfInterrogation(20));
}
@Override
public void newASdu(Connection connection, ASdu aSdu) {
log.debug("Got new ASdu:" + aSdu.toString());
}
@Override
public void connectionClosed(Connection connection, IOException e) {
}
@Override
public void dataTransferStateChanged(Connection connection, boolean b) {
}
}

@ -0,0 +1,56 @@
package com.xydl.cac.iec104;
import lombok.extern.slf4j.Slf4j;
import org.openmuc.j60870.*;
import java.io.IOException;
@Slf4j
public class Iec104Server implements ServerEventListener {
Server _server;
int idCounter = 1;
public boolean started = false;
public Integer port = null;
public Iec104Server() {
}
public void start(int port) throws Exception {
if (!started) {
_server = Server.builder()
.setPort(port)
.setIoaFieldLength(3)
.setCommonAddressFieldLength(2)
.setCotFieldLength(2)
.build();
_server.start(this);
started = true;
this.port = port;
log.info("已启动IEC104服务端在" + port + "端口");
}
}
public void stop() {
if (_server != null) {
_server.stop();
log.info("已停止IEC104服务端于" + port + "端口");
}
started = false;
}
@Override
public ConnectionEventListener connectionIndication(Connection connection) {
return new ServerConnectionEventListener(connection, idCounter++);
}
@Override
public void serverStoppedListeningIndication(IOException e) {
}
@Override
public void connectionAttemptFailed(IOException e) {
}
}

@ -0,0 +1,94 @@
package com.xydl.cac.iec104;
import lombok.extern.slf4j.Slf4j;
import org.openmuc.j60870.*;
import org.openmuc.j60870.ie.*;
import java.io.EOFException;
import java.io.IOException;
@Slf4j
public class ServerConnectionEventListener implements ConnectionEventListener {
Connection connection;
int connectionId;
boolean selected = false;
public ServerConnectionEventListener(Connection connection, int connectionId) {
this.connection = connection;
this.connectionId = connectionId;
}
@Override
public void newASdu(Connection connection, ASdu aSdu) {
log.debug("Got new ASdu:" + aSdu.toString());
InformationObject informationObject = null;
try {
switch (aSdu.getTypeIdentification()) {
// interrogation command
case C_IC_NA_1:
log.debug("Got interrogation command (100). Will send scaled measured values.");
connection.sendConfirmation(aSdu);
// example GI response values
connection.send(new ASdu(ASduType.M_ME_NB_1, true, CauseOfTransmission.INTERROGATED_BY_STATION,
false, false, 0, aSdu.getCommonAddress(),
new InformationObject(1, new InformationElement[][]{
{new IeScaledValue(-32768), new IeQuality(false, false, false, false, false)},
{new IeScaledValue(10), new IeQuality(false, false, false, false, false)},
{new IeScaledValue(-5),
new IeQuality(false, false, false, false, false)}})));
connection.sendActivationTermination(aSdu);
break;
case C_SC_NA_1:
informationObject = aSdu.getInformationObjects()[0];
IeSingleCommand singleCommand = (IeSingleCommand) informationObject
.getInformationElements()[0][0];
if (informationObject.getInformationObjectAddress() != 5000) {
break;
}
if (singleCommand.isSelect()) {
log.debug("Got single command (45) with select true. Select command.");
selected = true;
connection.sendConfirmation(aSdu);
} else if (!singleCommand.isSelect() && selected) {
log.debug("Got single command (45) with select false. Execute selected command.");
selected = false;
connection.sendConfirmation(aSdu);
} else {
log.debug("Got single command (45) with select false. But no command is selected, no execution.");
}
break;
case C_CS_NA_1:
IeTime56 ieTime56 = new IeTime56(System.currentTimeMillis());
log.debug("Got Clock synchronization command (103). Send current time: " + ieTime56.toString());
connection.synchronizeClocks(aSdu.getCommonAddress(), ieTime56);
break;
case C_SE_NB_1:
log.debug("Got Set point command, scaled value (49)");
break;
default:
log.debug("Got unknown request: " + aSdu.toString(),
". Send negative confirm with CoT UNKNOWN_TYPE_ID(44)");
connection.sendConfirmation(aSdu, aSdu.getCommonAddress(), true,
CauseOfTransmission.UNKNOWN_TYPE_ID);
}
} catch (EOFException e) {
log.debug("Will quit listening for commands on connection (" + connectionId,
") because socket was closed.");
} catch (IOException e) {
log.debug("Will quit listening for commands on connection (" + connectionId, ") because of error: ",
e.getMessage());
}
}
@Override
public void connectionClosed(Connection connection, IOException e) {
}
@Override
public void dataTransferStateChanged(Connection connection, boolean b) {
}
}
Loading…
Cancel
Save