package org.openmuc.openiec61850.app;
|
|
import java.io.IOException;
|
import java.util.ArrayList;
|
import java.util.List;
|
|
import org.openmuc.openiec61850.BasicDataAttribute;
|
import org.openmuc.openiec61850.BdaFloat32;
|
import org.openmuc.openiec61850.BdaFloat64;
|
import org.openmuc.openiec61850.BdaInt16;
|
import org.openmuc.openiec61850.BdaInt16U;
|
import org.openmuc.openiec61850.BdaInt32;
|
import org.openmuc.openiec61850.BdaInt32U;
|
import org.openmuc.openiec61850.BdaInt64;
|
import org.openmuc.openiec61850.BdaInt8;
|
import org.openmuc.openiec61850.BdaInt8U;
|
import org.openmuc.openiec61850.Fc;
|
import org.openmuc.openiec61850.ModelNode;
|
import org.openmuc.openiec61850.SclParseException;
|
import org.openmuc.openiec61850.ServerEventListener;
|
import org.openmuc.openiec61850.ServerModel;
|
import org.openmuc.openiec61850.ServerSap;
|
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 ConsoleServer {
|
|
private static final String WRITE_VALUE_KEY = "w";
|
private static final String WRITE_VALUE_KEY_DESCRIPTION = "write value to model node";
|
|
private static final String PRINT_SERVER_MODEL_KEY = "p";
|
private static final String PRINT_SERVER_MODEL_KEY_DESCRIPTION = "print server's model";
|
|
private static final IntCliParameter portParam = new CliParameterBuilder("-p")
|
.setDescription("The port to listen on. On unix based systems you need root privilages for ports < 1000.")
|
.buildIntParameter("port", 102);
|
|
private static final StringCliParameter modelFileParam = new CliParameterBuilder("-m")
|
.setDescription("The SCL file that contains the server's information model.")
|
.setMandatory()
|
.buildStringParameter("model-file");
|
|
private static ServerModel serverModel;
|
private static final ActionProcessor actionProcessor = new ActionProcessor(new ActionExecutor());
|
|
private static ServerSap serverSap = null;
|
|
private static class EventListener implements ServerEventListener {
|
|
@Override
|
public void serverStoppedListening(ServerSap serverSap) {
|
System.out.println("The SAP stopped listening");
|
}
|
|
@Override
|
public List<ServiceError> write(List<BasicDataAttribute> bdas) {
|
for (BasicDataAttribute bda : bdas) {
|
System.out.println("got a write request: " + bda);
|
/*
|
System.out.println("got a write request: " + bda.getReference().toString()
|
+ " value is: " + ((BdaFloat32) bda).getFloat());
|
BasicDataAttribute bdat = (BasicDataAttribute) serverModel.findModelNode(bda.getReference(),
|
Fc.fromString("SP"));
|
System.out.println("got a write rest: " + bdat.getReference().toString()
|
+ " value is: " + ((BdaFloat32) bdat).getFloat());
|
*/
|
}
|
return null;
|
}
|
}
|
|
private static class ActionExecutor implements ActionListener {
|
|
@Override
|
public void actionCalled(String actionKey) throws ActionException {
|
try {
|
switch (actionKey) {
|
case PRINT_SERVER_MODEL_KEY:
|
System.out.println("** Printing model.");
|
|
System.out.println(serverModel);
|
|
break;
|
case WRITE_VALUE_KEY:
|
System.out.println("** Reading model from file.");
|
|
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 BasicDataAttribute)) {
|
System.out.println("The given model node is not a basic data attribute.");
|
return;
|
}
|
|
BasicDataAttribute bda = (BasicDataAttribute) serverModel.findModelNode(reference,
|
Fc.fromString(fcString));
|
|
System.out.println("Enter value to write: ");
|
String valueString = actionProcessor.getReader().readLine();
|
|
try {
|
setBdaValue(bda, valueString);
|
} catch (Exception e) {
|
System.out.println(
|
"The console server does not support writing this type of basic data attribute.");
|
return;
|
}
|
|
List<BasicDataAttribute> bdas = new ArrayList<>();
|
bdas.add(bda);
|
serverSap.setValues(bdas);
|
|
System.out.println("Successfully wrote data.");
|
System.out.println(bda);
|
|
break;
|
|
default:
|
break;
|
}
|
} catch (Exception e) {
|
throw new ActionException(e);
|
}
|
}
|
|
private void setBdaValue(BasicDataAttribute bda, String valueString) {
|
if (bda instanceof BdaFloat32) {
|
float value = Float.parseFloat(valueString);
|
((BdaFloat32) bda).setFloat(value);
|
}
|
else if (bda instanceof BdaFloat64) {
|
double value = Float.parseFloat(valueString);
|
((BdaFloat64) bda).setDouble(value);
|
}
|
else if (bda instanceof BdaInt8) {
|
byte value = Byte.parseByte(valueString);
|
((BdaInt8) bda).setValue(value);
|
}
|
else if (bda instanceof BdaInt8U) {
|
short value = Short.parseShort(valueString);
|
((BdaInt8U) bda).setValue(value);
|
}
|
else if (bda instanceof BdaInt16) {
|
short value = Short.parseShort(valueString);
|
((BdaInt16) bda).setValue(value);
|
}
|
else if (bda instanceof BdaInt16U) {
|
int value = Integer.parseInt(valueString);
|
((BdaInt16U) bda).setValue(value);
|
}
|
else if (bda instanceof BdaInt32) {
|
int value = Integer.parseInt(valueString);
|
((BdaInt32) bda).setValue(value);
|
}
|
else if (bda instanceof BdaInt32U) {
|
long value = Long.parseLong(valueString);
|
((BdaInt32U) bda).setValue(value);
|
}
|
else if (bda instanceof BdaInt64) {
|
long value = Long.parseLong(valueString);
|
((BdaInt64) bda).setValue(value);
|
}
|
else {
|
throw new IllegalArgumentException();
|
}
|
}
|
|
@Override
|
public void quit() {
|
System.out.println("** Stopping server.");
|
serverSap.stop();
|
return;
|
}
|
}
|
|
public static void main(String[] args) throws IOException {
|
|
List<CliParameter> cliParameters = new ArrayList<>();
|
cliParameters.add(modelFileParam);
|
cliParameters.add(portParam);
|
|
CliParser cliParser = new CliParser("openiec61850-console-server", "An IEC 61850 MMS console server.");
|
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);
|
}
|
|
List<ServerSap> serverSaps = null;
|
try {
|
serverSaps = ServerSap.getSapsFromSclFile(modelFileParam.getValue());
|
} catch (SclParseException e) {
|
System.out.println("Error parsing SCL/ICD file: " + e.getMessage());
|
return;
|
}
|
|
serverSap = serverSaps.get(0);
|
serverSap.setPort(portParam.getValue());
|
|
Runtime.getRuntime().addShutdownHook(new Thread() {
|
@Override
|
public void run() {
|
if (serverSap != null) {
|
serverSap.stop();
|
}
|
System.out.println("Server was stopped.");
|
}
|
});
|
|
serverModel = serverSap.getModelCopy();
|
|
BasicDataAttribute bda = (BasicDataAttribute) serverModel.findModelNode("ZJDYBTSE/ncdGGIO1.Para2.setMag.f",
|
Fc.fromString("SP"));
|
((BdaFloat32) bda).setFloat((float) 13.5);
|
List<BasicDataAttribute> bdas = new ArrayList<>();
|
bdas.add(bda);
|
serverSap.setValues(bdas);
|
|
serverSap.startListening(new EventListener());
|
|
actionProcessor.addAction(new Action(PRINT_SERVER_MODEL_KEY, PRINT_SERVER_MODEL_KEY_DESCRIPTION));
|
actionProcessor.addAction(new Action(WRITE_VALUE_KEY, WRITE_VALUE_KEY_DESCRIPTION));
|
|
actionProcessor.start();
|
}
|
}
|