feat: 增加iec104底层组件
parent
7bc95e6e6a
commit
2a3e2902cb
@ -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…
Reference in New Issue