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