Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.openmuc.jdlms.app.ConsoleApp Maven / Gradle / Ivy
/*
* Copyright 2012-15 Fraunhofer ISE
*
* This file is part of jDLMS.
* For more information visit http://www.openmuc.org
*
* jDLMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* jDLMS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with jDLMS. If not, see .
*
*/
package org.openmuc.jdlms.app;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeoutException;
import org.openmuc.jdlms.AccessResultCode;
import org.openmuc.jdlms.GetResult;
import org.openmuc.jdlms.ObisCode;
import org.openmuc.jdlms.datatypes.BitString;
import org.openmuc.jdlms.datatypes.CosemDateFormat;
import org.openmuc.jdlms.datatypes.DataObject;
import org.openmuc.jdlms.interfaceclass.InterfaceClass;
import org.openmuc.jdlms.interfaceclass.attribute.AttributeClass;
import org.openmuc.jdlms.interfaceclass.attribute.AttributeDirectory;
import org.openmuc.jdlms.interfaceclass.attribute.AttributeDirectory.AttributeNotFoundException;
import org.openmuc.jdlms.interfaceclass.method.MethodDirectory;
import org.openmuc.jdlms.interfaceclass.method.MethodDirectory.MethodNotFoundException;
abstract class ConsoleApp {
private static final String DATA_INPUT_FORMAT = ":";
private static final String POSSIBLE_DATA_TYPES = "(b)oolean / (f)loat / (d)ouble / (l)ong / (i)nteger / (o)ctet";
private static final String SCAN_FORMAT = "%-30s%-40s%-17s%s\n";
private final BufferedReader inputReader;
public ConsoleApp() {
this.inputReader = new BufferedReader(new InputStreamReader(System.in));
}
public final void processRead() throws IOException {
System.out.println("Enter: " + nameFormat());
String requestParameter = inputReader.readLine();
GetResult result;
try {
result = callGet(requestParameter);
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.err.println("Failed to process read.");
return;
} catch (IllegalArgumentException e) {
System.err.printf(e.getMessage());
return;
}
AccessResultCode resultCode = result.resultCode();
if (resultCode == AccessResultCode.SUCCESS) {
System.out.println("Result Code: " + result.resultCode());
DataObject resultData = result.resultData();
printType(resultData);
}
else {
System.err.printf("Failed to read. AccessResultCode: %s\n", resultCode);
}
}
public final void processScan() throws IOException {
System.out.println("** Scan started...");
GetResult scanResult;
try {
scanResult = callScan();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.err.println("Failed to scan. Timed out. Try again.");
return;
}
if (scanResult.resultCode() != AccessResultCode.SUCCESS) {
System.err.println("Device sent error code " + scanResult.resultCode().name());
return;
}
DataObject root = scanResult.resultData();
List objectArray = root.value();
System.out.println("Scanned addresses:");
System.out.printf(SCAN_FORMAT, "Address", "Description", "AccessMode", "Selective Access");
for (DataObject objectDef : objectArray) {
List defItems = objectDef.value();
Integer classId = defItems.get(0).value();
classId &= 0xFF;
Number version = defItems.get(1).value();
byte[] logicalName = defItems.get(2).value();
ObisCode obisCode = new ObisCode(logicalName);
List accessRight = defItems.get(3).value();
List attributes = accessRight.get(0).value();
List methods = accessRight.get(1).value();
InterfaceClass interfaceClass = InterfaceClass.interfaceClassFor(classId, version.intValue());
String classIdStr = interfaceClass.name();
System.out.printf("%-13s %s\n", obisCode.medium(), classIdStr);
printAttributes(classId, interfaceClass, obisCode, attributes);
if (!methods.isEmpty()) {
printMethods(classId, interfaceClass, obisCode, methods);
}
System.out.println();
}
}
private void printAttributes(int classId, InterfaceClass interfaceClass, ObisCode obisCode,
List attributes) {
System.out.println("Attributes:");
for (DataObject attributeAccess : attributes) {
List value = attributeAccess.value();
Number attributeId = value.get(0).value();
Number accessModeI = value.get(1).value();
AccessMode accessMode = AccessMode.accessModeFor(accessModeI.intValue() & 0xFF);
DataObject accessSelectors = value.get(2);
String attributeIdStr;
Number intValue = attributeId.intValue();
int attributeId2 = intValue.intValue() & 0xFF;
try {
AttributeClass attributeClass = AttributeDirectory.attributeClassFor(interfaceClass, attributeId2);
attributeIdStr = String.format("%s", attributeClass.attributeName(), attributeClass.attributeId());
} catch (AttributeNotFoundException e) {
attributeIdStr = String.valueOf(attributeId2);
}
StringBuilder selectiveAccessB = new StringBuilder();
if (accessSelectors.isNull()) {
selectiveAccessB.append("-");
}
else {
List slectors = accessSelectors.value();
for (DataObject selector : slectors) {
Number sNumber = selector.value();
selectiveAccessB.append(String.format("%d, ", sNumber.intValue()));
}
}
String attributeAddress = String.format("%d/%s/%d", classId, obisCode.toDecimal(),
attributeId.intValue() & 0xFF);
System.out.printf(SCAN_FORMAT, attributeAddress, attributeIdStr, accessMode, selectiveAccessB.toString());
}
}
private void printMethods(int classId, InterfaceClass interfaceClass, ObisCode obisCode, List methods) {
System.out.println("Methods:");
for (DataObject dataObject : methods) {
List methodAccessItem = dataObject.value();
Number methodId = methodAccessItem.get(0).value();
Number accessModeId = methodAccessItem.get(1).value();
AccessMode accessMode = AccessMode.accessModeFor(accessModeId.intValue());
String methodAddress = String.format("%d/%s/%d", classId, obisCode.toDecimal(), methodId.intValue() & 0xFF);
String methoIdStr;
try {
methoIdStr = MethodDirectory.methodClassFor(interfaceClass, methodId.intValue()).methodName();
} catch (MethodNotFoundException e) {
methoIdStr = "";
}
System.out.printf(SCAN_FORMAT, methodAddress, methoIdStr, accessMode, "");
}
}
private enum AccessMode {
NO_ACCESS(0),
READ_ONLY(1),
WRITE_ONLY(2),
READ_AND_WRITE(3),
AUTHENTICATED_READ_ONLY(4),
AUTHENTICATED_WRITE_ONLY(5),
AUTHENTICATED_READ_AND_WRITE(6),
UNKNOWN_ACCESS_MODE(-1);
private int code;
private AccessMode(int code) {
this.code = code;
}
public static AccessMode accessModeFor(int code) {
for (AccessMode accessMode : values()) {
if (accessMode.code == code) {
return accessMode;
}
}
return UNKNOWN_ACCESS_MODE;
}
}
public final void processWrite() throws IOException {
System.out.println("Enter: " + nameFormat());
String address = inputReader.readLine();
System.out.println("Enter: " + DATA_INPUT_FORMAT);
System.out.println("possible data types: " + POSSIBLE_DATA_TYPES);
String inputData = inputReader.readLine();
DataObject dataToWrite = buildDataObject(inputData);
AccessResultCode resultCode = callSet(address, dataToWrite);
if (resultCode == AccessResultCode.SUCCESS) {
System.out.println("Result Code: " + resultCode);
}
else {
System.err.printf("Failed to write. AccessResultCode: %s\n", resultCode);
}
}
public abstract void close();
protected abstract String nameFormat();
protected abstract GetResult callGet(String requestParameter) throws IOException, TimeoutException;
protected abstract AccessResultCode callSet(String requestParameter, DataObject dataToWrite) throws IOException;
protected abstract GetResult callScan() throws IOException, TimeoutException;
private void printType(DataObject resultData) {
printType(resultData, 0);
}
private void printType(DataObject resultData, int shiftChars) {
String shift;
if (shiftChars > 0) {
shift = String.format("%" + shiftChars + "s%s", " ", "|- ");
}
else {
shift = "";
}
String message = String.format("%s Value: ", resultData.choiceIndex().name());
if (resultData.isBoolean()) {
Boolean boolVal = resultData.value();
System.out.printf(shift + message + boolVal.toString());
}
else if (resultData.isNumber()) {
Number number = resultData.value();
System.out.println(shift + message + number.toString());
}
else if (resultData.isByteArray()) {
byte[] value = resultData.value();
System.out.println(shift + message + Arrays.toString(value));
}
else if (resultData.isBitString()) {
BitString value = resultData.value();
System.out.println(shift + message + Arrays.toString(value.bitString()));
}
else if (resultData.isCosemDateFormat()) {
CosemDateFormat value = resultData.value();
System.out.println(shift + message + value.toCalendar().getTime().toString());
}
else if (resultData.isComplex()) {
System.out.println(shift + message);
List complex = resultData.value();
for (DataObject data : complex) {
printType(data, shiftChars + 3);
}
}
else {
System.err.println(shift + "Value is undefined type");
}
}
private DataObject buildDataObject(String line) {
String[] arguments = line.split(":");
if (arguments.length != 2) {
throw new IllegalArgumentException(String.format("Wrong number of arguments. %s", DATA_INPUT_FORMAT));
}
String dataTypeString = arguments[0];
String dataString = arguments[1];
char datatype = dataTypeString.toUpperCase().charAt(0);
DataObject dataObject;
switch (datatype) {
case 'S':
short sData = Short.parseShort(dataString);
dataObject = DataObject.newInteger16Data(sData);
break;
case 'I':
int iData = Integer.parseInt(dataString);
dataObject = DataObject.newInteger32Data(iData);
break;
case 'L':
Long lData = Long.parseLong(dataString);
dataObject = DataObject.newInteger64Data(lData);
break;
case 'F':
float fData = Float.parseFloat(dataString);
dataObject = DataObject.newFloat32Data(fData);
break;
case 'D':
double dData = Double.parseDouble(dataString);
dataObject = DataObject.newFloat64Data(dData);
break;
case 'B':
boolean bData = Boolean.parseBoolean(dataString);
dataObject = DataObject.newBoolData(bData);
break;
default:
throw new IllegalArgumentException(String.format("Wrong data type. %s", POSSIBLE_DATA_TYPES));
}
return dataObject;
}
}