Skip to content
Snippets Groups Projects
Commit 03c452a1 authored by Guillaume PICHON's avatar Guillaume PICHON
Browse files

Correction of array writing, and correct typing of unsigned values.

parent c377ec5f
Branches
No related tags found
No related merge requests found
......@@ -11,7 +11,7 @@
<groupId>fr.soleil.deviceservers</groupId>
<artifactId>OpcUaProxy</artifactId>
<version>1.1.1</version>
<version>1.1.2</version>
<name>OpcUaProxy</name>
<description>Proxy device between OPCUA and Tango</description>
......
......@@ -85,7 +85,7 @@ public abstract class AOpcUaSubscriber implements IAttributeValueConsumer {
+ subscriptionResultMap.size() + " OpcUa nodes and " + nbAttributes.toString() + " attributes");
}
protected void createTangoAttributes(SubscriptionResult subscriptionResult) {
protected int createTangoAttributes(SubscriptionResult subscriptionResult) {
Map<OpcUaAttributeReference, Set<OpcUaSubscribedAttribute>> subscriptionResultMap = subscriptionResult
.getAttributes();
MutableInt nbAttributes = new MutableInt();
......@@ -120,6 +120,7 @@ public abstract class AOpcUaSubscriber implements IAttributeValueConsumer {
});
getLogger().info("New subscription " + subscriptionResult.getSubscriptionId().toString() + " for "
+ subscriptionResultMap.size() + " OpcUa nodes and " + nbAttributes.toString() + " attributes");
return nbAttributes.intValue();
}
protected void removeAttributeForSubscription(UInteger subId) throws DevFailed {
......
......@@ -3,12 +3,15 @@ package fr.soleil.opcuaproxy.attributes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tango.DeviceState;
import org.tango.attribute.AttributeTangoType;
import org.tango.server.StateMachineBehavior;
import org.tango.server.attribute.AttributeConfiguration;
import org.tango.server.attribute.AttributeValue;
import org.tango.server.attribute.IAttributeBehavior;
import fr.esrf.Tango.AttrDataFormat;
import fr.esrf.Tango.DevFailed;
import fr.soleil.opcuaproxy.attributes.OpcUaTangoUtils.FullTangoType;
public abstract class AOpcUaAttribute implements IAttributeBehavior, Comparable<AOpcUaAttribute> {
static final Logger logger = LoggerFactory.getLogger(AOpcUaAttribute.class);
......@@ -17,6 +20,7 @@ public abstract class AOpcUaAttribute implements IAttributeBehavior, Comparable<
private AttributeConfiguration configuration;
private IOpcUaNodeWriter nodeWriter;
private Class<? extends Object> opcuaClass;
private FullTangoType fullTangoType;
protected AOpcUaAttribute(AttributeConfiguration configuration, IOpcUaNodeWriter nodeWriter,
AOpcUaAttributeParameters parameters, Class<? extends Object> opcuaClass) {
......@@ -25,6 +29,14 @@ public abstract class AOpcUaAttribute implements IAttributeBehavior, Comparable<
this.nodeWriter = nodeWriter;
this.parameters = parameters;
this.opcuaClass = opcuaClass;
AttributeTangoType attrTangoType = null;
try {
attrTangoType = AttributeTangoType.getTypeFromTango(configuration.getTangoType());
} catch (DevFailed e) {
logger.error("This error should not happen. It's a bug.", e);
}
AttrDataFormat attrDataFormat = configuration.getFormat();
fullTangoType = new FullTangoType(attrTangoType, attrDataFormat);
}
/**
......@@ -66,6 +78,10 @@ public abstract class AOpcUaAttribute implements IAttributeBehavior, Comparable<
}
}
public FullTangoType getFullTangoType() throws DevFailed {
return fullTangoType;
}
@Override
public int compareTo(AOpcUaAttribute other) {
String otherName = "";
......
......@@ -8,6 +8,7 @@ import org.tango.server.attribute.AttributeValue;
import fr.esrf.Tango.AttrWriteType;
import fr.esrf.Tango.DevFailed;
import fr.soleil.opcuaproxy.attributes.OpcUaTangoUtils.FullTangoType;
import fr.soleil.opcuaproxy.connector.OpcUaValue;
/**
......@@ -78,15 +79,15 @@ public class OpcUaPolledAttribute extends AOpcUaAttribute {
}
// Note for refactoring : create a configuration builder.
config.getAttributeProperties().setDescription(descBuilder.toString());
config.setType(OpcUaTangoUtils.getTangoClass(firstValue));
FullTangoType tangoType = OpcUaTangoUtils.getTangoType(firstValue);
config.setTangoType(tangoType.getType().getTangoIDLType(), tangoType.getFormat());
if (!parameters.getWriteNodes().isEmpty()) {
config.setWritable(AttrWriteType.READ_WRITE);
} else {
config.setWritable(AttrWriteType.READ);
}
OpcUaPolledAttribute attribute = new OpcUaPolledAttribute(config, nodeReaderWriter, parameters,
valueClass);
OpcUaPolledAttribute attribute = new OpcUaPolledAttribute(config, nodeReaderWriter, parameters, valueClass);
return attribute;
}
}
......@@ -15,86 +15,180 @@ import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UByte;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.ULong;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort;
import org.tango.attribute.AttributeTangoType;
import org.tango.utils.DevFailedUtils;
import fr.esrf.Tango.AttrDataFormat;
import fr.esrf.Tango.DevFailed;
public abstract class OpcUaTangoUtils {
private static final Map<Class<? extends Object>, Class<? extends Object>> opcuaToTango = new HashMap<>();
private static final Map<Class<? extends Object>, AttributeTangoType> opcuaToTangoType = new HashMap<>();
static {
opcuaToTango.put(UByte.class, Byte.class);
opcuaToTango.put(UShort.class, Integer.class);
opcuaToTango.put(UInteger.class, Long.class);
opcuaToTango.put(ULong.class, Long.class);
opcuaToTango.put(DateTime.class, String.class);
opcuaToTango.put(NodeId.class, String.class);
opcuaToTango.put(LocalizedText.class, String.class);
opcuaToTango.put(ByteString.class, String.class);
opcuaToTangoType.put(UByte.class, AttributeTangoType.DEVUCHAR);
opcuaToTangoType.put(UShort.class, AttributeTangoType.DEVUSHORT);
opcuaToTangoType.put(UInteger.class, AttributeTangoType.DEVULONG);
opcuaToTangoType.put(ULong.class, AttributeTangoType.DEVULONG64);
opcuaToTangoType.put(DateTime.class, AttributeTangoType.DEVSTRING);
opcuaToTangoType.put(NodeId.class, AttributeTangoType.DEVSTRING);
opcuaToTangoType.put(LocalizedText.class, AttributeTangoType.DEVSTRING);
opcuaToTangoType.put(ByteString.class, AttributeTangoType.DEVSTRING);
}
public static class FullTangoType {
private AttrDataFormat format;
private AttributeTangoType type;
public FullTangoType(AttributeTangoType type, AttrDataFormat format) {
super();
this.format = format;
this.type = type;
}
public AttrDataFormat getFormat() {
return format;
}
public AttributeTangoType getType() {
return type;
}
public String toString() {
return format.toString() + " " + type.name();
}
public Class<? extends Object> getTangoClass() {
Class<? extends Object> tangoClass = type.getType();
if (format == AttrDataFormat.SPECTRUM) {
tangoClass = Array.newInstance(tangoClass, 0).getClass();
} else if (format == AttrDataFormat.IMAGE) {
Class<? extends Object> tangoSubClass = Array.newInstance(tangoClass, 0).getClass();
tangoClass = Array.newInstance(tangoSubClass, 0).getClass();
}
return tangoClass;
}
}
private OpcUaTangoUtils() {
}
public static Class<? extends Object> getTangoClass(Object opcuaValue) {
return getTangoClass(opcuaValue, false);
public static FullTangoType getTangoType(Object opcuaValue) {
return getTangoType(opcuaValue, false);
}
public static Class<? extends Object> getTangoClass(Class<? extends Object> opcuaClass) {
Class<? extends Object> tangoClass = opcuaToTango.get(opcuaClass);
if (tangoClass == null) {
public static FullTangoType getTangoType(Class<? extends Object> opcuaClass) {
AttributeTangoType tangoType = opcuaToTangoType.get(opcuaClass);
AttrDataFormat format = AttrDataFormat.SCALAR;
if (tangoType == null) {
if (opcuaClass.isArray()) {
Class<?> tangoArrayClass = opcuaToTango.get(opcuaClass.getComponentType());
if (tangoArrayClass != null) {
tangoClass = Array.newInstance(tangoArrayClass, 0).getClass();
Class<?> opcuaInnerClass = opcuaClass.getComponentType();
format = AttrDataFormat.SPECTRUM;
if (opcuaInnerClass != null) {
if (opcuaInnerClass.isArray()) {
opcuaInnerClass = opcuaInnerClass.getComponentType();
format = AttrDataFormat.IMAGE;
}
if (opcuaInnerClass != null && !opcuaInnerClass.isArray()) { // 2D max
tangoType = opcuaToTangoType.get(opcuaInnerClass);
}
}
return tangoClass;
}
}
FullTangoType fullTangoType = null;
if (tangoType != null) {
fullTangoType = new FullTangoType(tangoType, format);
}
return fullTangoType;
}
private static Class<? extends Object> getTangoClass(Object opcuaValue, boolean nullIfNative) {
private static FullTangoType getTangoType(Object opcuaValue, boolean nullIfNative) {
FullTangoType fullTangoType = null;
Class<? extends Object> opcuaClass = opcuaValue.getClass();
Class<? extends Object> tangoClass = opcuaToTango.get(opcuaClass);
if (tangoClass == null) {
AttributeTangoType tangoType = opcuaToTangoType.get(opcuaClass);
AttrDataFormat format = AttrDataFormat.SCALAR;
if (tangoType == null) {
if (opcuaClass.isArray()) {
Class<?> tangoArrayClass = opcuaToTango.get(opcuaClass.getComponentType());
if (tangoArrayClass == null) {
Class<? extends Object> arrayInnerClass = extractArrayInnerClass(opcuaValue);
AttributeTangoType tangoArrayType = getTangoBasicType(arrayInnerClass, nullIfNative);
format = AttrDataFormat.SPECTRUM;
if (tangoArrayType == null && arrayInnerClass.isArray()) {
format = AttrDataFormat.IMAGE;
if (Array.getLength(opcuaValue) > 0) {
tangoArrayClass = getTangoClass(Array.get(opcuaValue, 0), nullIfNative);
Class<? extends Object> imgInnerClass = extractArrayInnerClass(Array.get(opcuaValue, 0));
AttributeTangoType tangoImgType = getTangoBasicType(imgInnerClass, nullIfNative);
tangoArrayType = tangoImgType;
}
}
if (tangoArrayClass != null) {
tangoClass = Array.newInstance(tangoArrayClass, 0).getClass();
if (tangoArrayType != null) {
fullTangoType = new FullTangoType(tangoArrayType, format);
}
} else if (!nullIfNative) {
tangoClass = opcuaClass;
try {
fullTangoType = new FullTangoType(AttributeTangoType.getTypeFromClass(opcuaClass), format);
} catch (DevFailed e) {
fullTangoType = null;
}
}
return tangoClass;
} else {
fullTangoType = new FullTangoType(tangoType, format);
}
return fullTangoType;
}
private static AttributeTangoType getTangoBasicType(Class<? extends Object> clazz, boolean nullIfNative) {
AttributeTangoType tangoType = opcuaToTangoType.get(clazz);
if( tangoType==null && !nullIfNative) {
try {
tangoType = AttributeTangoType.getTypeFromClass(clazz);
} catch (DevFailed e) {
tangoType = null;
}
}
return tangoType;
}
private static Class<? extends Object> extractArrayInnerClass(Object value) {
Class<? extends Object> clazz = value.getClass();
if (clazz.isArray()) {
clazz = clazz.getComponentType();
if (clazz == Object.class) {
if (Array.getLength(value) > 0 && Array.get(value, 0) != null) {
clazz = Array.get(value, 0).getClass();
} else {
clazz = null;
}
}
}
return clazz;
}
public static Object getOpcuaValue(Object tangoValue, Class<? extends Object> opcuaClass) {
Object opcuaValue = tangoValue;
if (tangoValue.getClass().isArray()) {
int length = Array.getLength(tangoValue);
opcuaValue = Array.newInstance(opcuaClass, length);
Class<? extends Object> opcuaInnerClass = opcuaClass.getComponentType();
opcuaValue = Array.newInstance(opcuaInnerClass, length);
for (int i = 0; i < length; i++) {
Object tangoIValue = Array.get(tangoValue, i);
Object opcuaIValue = getOpcuaValue(tangoIValue, opcuaClass);
Object opcuaIValue = getOpcuaValue(tangoIValue, opcuaInnerClass);
Array.set(opcuaValue, i, opcuaIValue);
}
} else {
Class<? extends Object> tangoClass = opcuaToTango.get(opcuaClass);
Class<? extends Object> tangoClass = null;
AttributeTangoType tangoType = opcuaToTangoType.get(opcuaClass);
if (tangoType != null) {
tangoClass = tangoType.getType();
}
if (tangoClass != null) {
if (opcuaClass == UByte.class) {
opcuaValue = UByte.valueOf(((Byte) tangoValue).byteValue());
} else if (opcuaClass == UShort.class) {
opcuaValue = UShort.valueOf(((Integer) tangoValue).intValue());
opcuaValue = UShort.valueOf(((Short) tangoValue).shortValue());
} else if (opcuaClass == UInteger.class) {
opcuaValue = UInteger.valueOf(((Long) tangoValue).longValue());
opcuaValue = UInteger.valueOf(((Integer) tangoValue).longValue());
} else if (opcuaClass == ULong.class) {
opcuaValue = ULong.valueOf(((Long) tangoValue).longValue());
} else if (opcuaClass == DateTime.class) {
......@@ -113,16 +207,16 @@ public abstract class OpcUaTangoUtils {
public static Object getTangoValue(Object opcuaValue) {
Class<? extends Object> opcuaClass = opcuaValue.getClass();
Class<? extends Object> tangoClass = getTangoClass(opcuaValue, true);
FullTangoType tangoType = getTangoType(opcuaValue, true);
Object tangoValue = opcuaValue;
if (tangoClass != null) {
if (!tangoClass.isArray()) {
if (tangoType != null) {
if (tangoType.format == AttrDataFormat.SCALAR) {
if (opcuaClass == UByte.class) {
tangoValue = Byte.valueOf(((UByte) opcuaValue).byteValue());
} else if (opcuaClass == UShort.class) {
tangoValue = Integer.valueOf(((UShort) opcuaValue).intValue());
tangoValue = Short.valueOf(((UShort) opcuaValue).shortValue());
} else if (opcuaClass == UInteger.class) {
tangoValue = Long.valueOf(((UInteger) opcuaValue).longValue());
tangoValue = Integer.valueOf(((UInteger) opcuaValue).intValue());
} else if (opcuaClass == ULong.class) {
tangoValue = Long.valueOf(((ULong) opcuaValue).longValue());
} else if (opcuaClass == DateTime.class) {
......@@ -134,10 +228,10 @@ public abstract class OpcUaTangoUtils {
} else if (opcuaClass == ByteString.class) {
tangoValue = ((ByteString) opcuaValue).toString();
}
} else {
int length = Array.getLength(opcuaValue);
tangoValue = Array.newInstance(tangoClass.getComponentType(), length);
//Class<? extends Object> arrayInnerClass = extractArrayInnerClass(opcuaValue);
tangoValue = Array.newInstance(tangoType.getTangoClass().getComponentType(), length);
for (int i = 0; i < length; i++) {
Object opcuaIValue = Array.get(opcuaValue, i);
Object tangoIValue = getTangoValue(opcuaIValue);
......@@ -148,7 +242,6 @@ public abstract class OpcUaTangoUtils {
return tangoValue;
}
public static Object parseArray(String arrayStrIn, Class<?> clazz) throws DevFailed {
ArrayParsingData arrayParsingData = parseSubArray(arrayStrIn, clazz);
return arrayParsingData.array;
......
......@@ -18,6 +18,7 @@ import fr.soleil.opcuaproxy.attributes.OpcUaPolledAttributeParameters;
import fr.soleil.opcuaproxy.attributes.OpcUaSubscribedAttribute;
import fr.soleil.opcuaproxy.attributes.OpcUaSubscribedAttributeParameters;
import fr.soleil.opcuaproxy.attributes.OpcUaTangoUtils;
import fr.soleil.opcuaproxy.attributes.OpcUaTangoUtils.FullTangoType;
public abstract class OpcUaAttributeFactory {
static final Logger logger = LoggerFactory.getLogger(OpcUaAttributeFactory.class);
......@@ -63,7 +64,8 @@ public abstract class OpcUaAttributeFactory {
}
// Note for refactoring : create a configuration builder.
config.getAttributeProperties().setDescription(descBuilder.toString());
config.setType(OpcUaTangoUtils.getTangoClass(firstValue));
FullTangoType tangoType = OpcUaTangoUtils.getTangoType(firstValue);
config.setTangoType(tangoType.getType().getTangoIDLType(), tangoType.getFormat());
if (!parameters.getWriteNodes().isEmpty()) {
config.setWritable(AttrWriteType.READ_WRITE);
} else {
......
......@@ -197,6 +197,7 @@ public class OpcUaConnector extends AOpcUaSubscriber {
}
}
if (isConnected()) {
try {
if (firstConnection) {
// Ask subscribers to subscribe.
OpcUaProxy.subscribeAll();
......@@ -204,6 +205,11 @@ public class OpcUaConnector extends AOpcUaSubscriber {
// Ask subscribers to resubscribe.
OpcUaProxy.resubscribeAll();
}
} catch (DevFailed e) {
throw e;
} catch (Exception e) {
logger.error("Unexpected error: " + e.getMessage(), e);
}
}
}
......@@ -271,7 +277,6 @@ public class OpcUaConnector extends AOpcUaSubscriber {
connectionLooper.setFirstConnection();
connectionExecutor.submit(connectionLooper);
logger.debug("init done for device {} ", deviceManager.getName());
}
......@@ -348,9 +353,11 @@ public class OpcUaConnector extends AOpcUaSubscriber {
SubscriptionResult result = createOPCUAAttributesByBrowsing(sessionSimpleNodeId, false,
requestedPublishingIntervalForDiagnostic, samplingIntervalForSubscriptionForDiagnostic,
Collections.emptySet(), this);
createTangoAttributes(result);
int nbCreated = createTangoAttributes(result);
if (nbCreated > 0) {
this.diagnosticAttributes = result;
}
}
@Command(name = "RemoveDiagnosticAttributes", inTypeDesc = "Remove the diagnostic attributes.", outTypeDesc = "")
public void removeDiagnosticAttributes() throws DevFailed {
......
......@@ -125,9 +125,9 @@ public class OpcUaMethod implements ICommandBehavior, Comparable<OpcUaMethod> {
+ tangoOpcUaObj.getOpcuaClass().getSimpleName() + "' received '"
+ opcUaResult.getClass().getSimpleName() + "'");
}
if (tangoOpcUaObj.getTangoClass() != tangoResult.getClass()) {
if (tangoOpcUaObj.getTangoType().getTangoClass() != tangoResult.getClass()) {
throw DevFailedUtils.newDevFailed("Wrong decoded output type. Expected '"
+ tangoOpcUaObj.getTangoClass().getSimpleName() + "' received '"
+ tangoOpcUaObj.getTangoType().toString() + "' received '"
+ tangoResult.getClass().getSimpleName() + "'");
}
}
......@@ -163,7 +163,7 @@ public class OpcUaMethod implements ICommandBehavior, Comparable<OpcUaMethod> {
if (arguments.length == 1) {
Argument argument = arguments[0];
TangoToOpcUaObject tangoToOpcUa = TangoToOpcUaObject.build(argument);
ioType.type = tangoToOpcUa.getTangoClass();
ioType.type = tangoToOpcUa.getTangoType().getTangoClass();
ioType.desc = getArgumentDescription(argument);
ioType.tangoOpcUaObjList = Collections.singletonList(tangoToOpcUa);
} else {
......@@ -176,9 +176,9 @@ public class OpcUaMethod implements ICommandBehavior, Comparable<OpcUaMethod> {
TangoToOpcUaObject tangoToOpcUa = TangoToOpcUaObject.build(argument);
ioType.tangoOpcUaObjList.add(tangoToOpcUa);
if (classPrec != null) {
ioType.allSameClass &= tangoToOpcUa.getTangoClass() == classPrec;
ioType.allSameClass &= tangoToOpcUa.getTangoType().getTangoClass() == classPrec;
}
classPrec = tangoToOpcUa.getTangoClass();
classPrec = tangoToOpcUa.getTangoType().getTangoClass();
}
if (ioType.allSameClass) {
ioType.type = Array.newInstance(classPrec, 0).getClass();
......
......@@ -6,23 +6,26 @@ import java.math.BigInteger;
import org.eclipse.milo.opcua.stack.core.BuiltinDataType;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.eclipse.milo.opcua.stack.core.types.structured.Argument;
import org.tango.attribute.AttributeTangoType;
import org.tango.utils.DevFailedUtils;
import fr.esrf.Tango.AttrDataFormat;
import fr.esrf.Tango.DevFailed;
import fr.soleil.opcuaproxy.attributes.OpcUaTangoUtils;
import fr.soleil.opcuaproxy.attributes.OpcUaTangoUtils.FullTangoType;
public class TangoToOpcUaObject {
private Class<? extends Object> tangoClass;
private FullTangoType tangoType;
private Class<? extends Object> opcuaClass;
private TangoToOpcUaObject(Class<? extends Object> tangoClass, Class<? extends Object> opcuaClass) {
private TangoToOpcUaObject(FullTangoType tangoType, Class<? extends Object> opcuaClass) {
super();
this.tangoClass = tangoClass;
this.tangoType = tangoType;
this.opcuaClass = opcuaClass;
}
public Class<? extends Object> getTangoClass() {
return tangoClass;
public FullTangoType getTangoType() {
return tangoType;
}
public Class<? extends Object> getOpcuaClass() {
......@@ -30,7 +33,7 @@ public class TangoToOpcUaObject {
}
public String toString() {
String tangoClassName = tangoClass != null ? tangoClass.getSimpleName() : "unknown";
String tangoClassName = tangoType != null ? tangoType.toString() : "unknown";
String opcuaClassName = opcuaClass != null ? opcuaClass.getSimpleName() : "unknown";
return tangoClassName + " <-> " + opcuaClassName;
}
......@@ -38,32 +41,32 @@ public class TangoToOpcUaObject {
public static TangoToOpcUaObject build(Argument argument) throws DevFailed {
NodeId dt = argument.getDataType();
Class<?> opcuaClass = BuiltinDataType.getBackingClass(dt);
Class<?> tangoClass = null;
FullTangoType tangoType = null;
if (opcuaClass != null) {
tangoClass = OpcUaTangoUtils.getTangoClass(opcuaClass);
tangoType = OpcUaTangoUtils.getTangoType(opcuaClass);
boolean isNative = opcuaClass.getPackage().equals(Integer.class.getPackage())
|| opcuaClass.getPackage().equals(BigInteger.class.getPackage());
if (tangoClass == null && isNative) {
tangoClass = opcuaClass;
if (tangoType == null && isNative) {
tangoType = new FullTangoType(AttributeTangoType.getTypeFromClass(opcuaClass), AttrDataFormat.SCALAR);
}
}
if (tangoClass == null || opcuaClass == null) {
if (tangoType == null || opcuaClass == null) {
throw DevFailedUtils.newDevFailed("No conversion available for data type " + dt);
}
if (argument.getArrayDimensions() != null && argument.getArrayDimensions().length > 0) {
if (argument.getArrayDimensions().length == 1) {
// Spectrum
tangoClass = Array.newInstance(tangoClass, 0).getClass();
tangoType = new FullTangoType(tangoType.getType(), AttrDataFormat.SPECTRUM);
opcuaClass = Array.newInstance(opcuaClass, 0).getClass();
} else if (argument.getArrayDimensions().length == 2) {
// Image
tangoClass = Array.newInstance(Array.newInstance(tangoClass, 0).getClass(), 0).getClass();
tangoType = new FullTangoType(tangoType.getType(), AttrDataFormat.IMAGE);
opcuaClass = Array.newInstance(Array.newInstance(opcuaClass, 0).getClass(), 0).getClass();
} else {
throw DevFailedUtils.newDevFailed("Too many dimensions for argument of type " + dt);
}
}
return new TangoToOpcUaObject(tangoClass, opcuaClass);
return new TangoToOpcUaObject(tangoType, opcuaClass);
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment