You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iec61850bean/src/main/java/org/openmuc/openiec61850/app/ConsoleClient.java

285 lines
11 KiB
Java

package org.openmuc.openiec61850.app;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import org.openmuc.openiec61850.ClientAssociation;
import org.openmuc.openiec61850.ClientEventListener;
import org.openmuc.openiec61850.ClientSap;
import org.openmuc.openiec61850.Fc;
import org.openmuc.openiec61850.FcModelNode;
import org.openmuc.openiec61850.ModelNode;
import org.openmuc.openiec61850.Report;
import org.openmuc.openiec61850.SclParseException;
import org.openmuc.openiec61850.ServerModel;
import org.openmuc.openiec61850.ServiceError;
import org.openmuc.openiec61850.internal.cli.Action;
import org.openmuc.openiec61850.internal.cli.ActionException;
import org.openmuc.openiec61850.internal.cli.ActionListener;
import org.openmuc.openiec61850.internal.cli.ActionProcessor;
import org.openmuc.openiec61850.internal.cli.CliParameter;
import org.openmuc.openiec61850.internal.cli.CliParameterBuilder;
import org.openmuc.openiec61850.internal.cli.CliParseException;
import org.openmuc.openiec61850.internal.cli.CliParser;
import org.openmuc.openiec61850.internal.cli.IntCliParameter;
import org.openmuc.openiec61850.internal.cli.StringCliParameter;
/**
*
* @author Stefan Feuerhahn
*
*/
public class ConsoleClient {
private static final String PRINT_MODEL_KEY = "m";
private static final String PRINT_MODEL_KEY_DESCRIPTION = "print model";
private static final String GET_DATA_VALUES_KEY = "r";
private static final String GET_DATA_VALUES_KEY_DESCRIPTION = "send GetDataValues request";
private static final String READ_ALL_DATA_KEY = "ra";
private static final String READ_ALL_DATA_KEY_DESCRIPTION = "update all data in the model";
private static final StringCliParameter hostParam = new CliParameterBuilder("-h")
.setDescription("The IP/domain address of the server you want to access.")
.setMandatory()
.buildStringParameter("host");
private static final IntCliParameter portParam = new CliParameterBuilder("-p")
.setDescription("The port to connect to.")
.buildIntParameter("port", 102);
private static final StringCliParameter modelFileParam = new CliParameterBuilder("-m").setDescription(
"The file name of the SCL file to read the model from. If this parameter is omitted the model will be read from the server device after connection.")
.buildStringParameter("model-file");
private static volatile ClientAssociation association;
private static ServerModel serverModel;
private static final ActionProcessor actionProcessor = new ActionProcessor(new ActionExecutor());
private static class EventListener implements ClientEventListener {
@Override
public void newReport(Report report) {
System.out.println("Received report: " + report);
}
@Override
public void associationClosed(IOException e) {
System.out.print("Received connection closed signal. Reason: ");
if (!e.getMessage().isEmpty()) {
System.out.println(e.getMessage());
}
else {
System.out.println("unknown");
}
actionProcessor.close();
}
}
private static class ActionExecutor implements ActionListener {
@Override
public void actionCalled(String actionKey) throws ActionException {
try {
switch (actionKey) {
case PRINT_MODEL_KEY:
System.out.println(serverModel);
break;
case READ_ALL_DATA_KEY:
System.out.print("Reading all data...");
association.getAllDataValues();
System.out.println("done");
break;
case GET_DATA_VALUES_KEY:
System.out.println("** Sending GetDataValues request.");
if (serverModel == null) {
System.out.println("You have to retrieve the model before reading data.");
return;
}
System.out.println("Enter reference to read (e.g. myld/MYLN0.do.da.bda): ");
String reference = actionProcessor.getReader().readLine();
System.out.println("Enter functional constraint of referenced node: ");
String fcString = actionProcessor.getReader().readLine();
Fc fc = Fc.fromString(fcString);
if (fc == null) {
System.out.println("Unknown functional constraint.");
return;
}
ModelNode modelNode = serverModel.findModelNode(reference, Fc.fromString(fcString));
if (modelNode == null) {
System.out.println(
"A model node with the given reference and functional constraint could not be found.");
return;
}
if (!(modelNode instanceof FcModelNode)) {
System.out.println("The given model node is not a functionally constraint model node.");
return;
}
FcModelNode fcModelNode = (FcModelNode) serverModel.findModelNode(reference,
Fc.fromString(fcString));
try {
association.getDataValues(fcModelNode);
} catch (ServiceError e) {
System.out.println("Service error: " + e.getMessage());
return;
} catch (IOException e) {
System.out.println("Fatal error: " + e.getMessage());
return;
}
System.out.println("Successfully read data.");
System.out.println(fcModelNode);
break;
default:
break;
}
} catch (Exception e) {
throw new ActionException(e);
}
}
@Override
public void quit() {
System.out.println("** Closing connection.");
association.close();
return;
}
}
public static void main(String[] args) {
List<CliParameter> cliParameters = new ArrayList<>();
cliParameters.add(hostParam);
cliParameters.add(portParam);
cliParameters.add(modelFileParam);
CliParser cliParser = new CliParser("openiec61850-console-client",
"A client application to access IEC 61850 MMS servers.");
cliParser.addParameters(cliParameters);
try {
cliParser.parseArguments(args);
} catch (CliParseException e1) {
System.err.println("Error parsing command line parameters: " + e1.getMessage());
System.out.println(cliParser.getUsageString());
System.exit(1);
}
InetAddress address;
try {
address = InetAddress.getByName(hostParam.getValue());
} catch (UnknownHostException e) {
System.out.println("Unknown host: " + hostParam.getValue());
return;
}
ClientSap clientSap = new ClientSap();
// alternatively you could use ClientSap(SocketFactory factory) to e.g. connect using SSL
// optionally you can set some association parameters (but usually the default should work):
// clientSap.setTSelRemote(new byte[] { 0, 1 });
// clientSap.setTSelLocal(new byte[] { 0, 0 });
try {
association = clientSap.associate(address, portParam.getValue(), null, new EventListener());
} catch (IOException e) {
System.out.println("Unable to connect to remote host.");
return;
}
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
association.close();
}
});
System.out.println("successfully connected");
if (modelFileParam.isSelected()) {
System.out.println("reading model from file...");
try {
serverModel = association.getModelFromSclFile(modelFileParam.getValue());
} catch (SclParseException e1) {
System.out.println("Error parsing SCL file: " + e1.getMessage());
return;
}
System.out.println("successfully read model");
}
else {
System.out.println("retrieving model...");
try {
serverModel = association.retrieveModel();
} catch (ServiceError e) {
System.out.println("Service error: " + e.getMessage());
return;
} catch (IOException e) {
System.out.println("Fatal error: " + e.getMessage());
return;
}
System.out.println("successfully read model");
}
actionProcessor.addAction(new Action(PRINT_MODEL_KEY, PRINT_MODEL_KEY_DESCRIPTION));
actionProcessor.addAction(new Action(GET_DATA_VALUES_KEY, GET_DATA_VALUES_KEY_DESCRIPTION));
actionProcessor.addAction(new Action(READ_ALL_DATA_KEY, READ_ALL_DATA_KEY_DESCRIPTION));
actionProcessor.start();
//
// // example for writing a variable:
// FcModelNode modCtlModel = (FcModelNode) serverModel.findModelNode("ied1lDevice1/CSWI1.Mod.ctlModel", Fc.CF);
// association.setDataValues(modCtlModel);
//
// // example for enabling reporting
// Urcb urcb = serverModel.getUrcb("ied1lDevice1/LLN0.urcb1");
// if (urcb == null) {
// System.out.println("ReportControlBlock not found");
// }
// else {
// association.getRcbValues(urcb);
// System.out.println("urcb name: " + urcb.getName());
// System.out.println("RptId: " + urcb.getRptId());
// System.out.println("RptEna: " + urcb.getRptEna().getValue());
// association.reserveUrcb(urcb);
// association.enableReporting(urcb);
// association.startGi(urcb);
// association.disableReporting(urcb);
// association.cancelUrcbReservation(urcb);
// }
//
// // example for reading a variable:
// FcModelNode totW = (FcModelNode) serverModel.findModelNode("ied1lDevice1/MMXU1.TotW", Fc.MX);
// BdaFloat32 totWmag = (BdaFloat32) totW.getChild("mag").getChild("f");
// BdaTimestamp totWt = (BdaTimestamp) totW.getChild("t");
// BdaQuality totWq = (BdaQuality) totW.getChild("q");
//
// while (true) {
// association.getDataValues(totW);
// System.out.println("got totW: mag " + totWmag.getFloat() + ", time " + totWt.getDate() + ", quality "
// + totWq.getValidity());
//
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// }
//
// }
}
}