RSISourceNode.java
package de.dlr.bt.stc.source.rsi.uas;
import java.util.concurrent.CompletableFuture;
import org.eclipse.milo.opcua.sdk.server.nodes.UaObjectNode;
import org.eclipse.milo.opcua.sdk.server.nodes.UaObjectTypeNode;
import org.eclipse.milo.opcua.stack.core.Identifiers;
import org.eclipse.milo.opcua.stack.core.UaException;
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
import org.eclipse.milo.opcua.stack.core.types.builtin.DateTime;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
import de.dlr.bt.stc.init.Register;
import de.dlr.bt.stc.opcuaserver.ANodeCreator;
import de.dlr.bt.stc.opcuaserver.NodeFactory;
import de.dlr.bt.stc.opcuaserver.STCNamespace;
import de.dlr.bt.stc.opcuaserver.STCNamespace.Folders;
import de.dlr.bt.stc.source.rsi.RSISource;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class RSISourceNode extends ANodeCreator {
@Register
public static void register() {
NodeFactory.getInstance().registerCreator(RSISource.class, RSISourceNode::new);
}
private static final String RSISOURCE_TYPE = "RSISourceType";
private static final String PORT = "Port";
private static final String DATATYPE = "DataType";
private static final String PATH = "Path";
private static final String RSIVALUE_TYPE = "RSIValueType";
private static final String VALUE = "Value";
private static final String LAST_UPDATE = "LastUpdate";
private UaObjectTypeNode sourceTypeNode;
private UaObjectTypeNode valueTypeNode;
private RSISourceNode(STCNamespace namespace) {
super(namespace, "stc", "sources", "rsisource");
}
@Override
public void createObjectType() {
var port = namespace.createObjectTypeComponent(PORT, namespace.newNodeId(nodePathType(PORT)),
Identifiers.Integer);
var datatype = namespace.createObjectTypeComponent(DATATYPE, namespace.newNodeId(nodePathType(DATATYPE)),
Identifiers.String);
var path = namespace.createObjectTypeComponent(PATH, namespace.newNodeId(nodePathType(PATH)),
Identifiers.String);
var value = namespace.createObjectTypeComponent(VALUE, namespace.newNodeId(nodePathType(VALUE)), NULLNODEID);
var lastupdate = namespace.createObjectTypeComponent(LAST_UPDATE,
namespace.newNodeId(nodePathType(LAST_UPDATE)), Identifiers.DateTime);
valueTypeNode = namespace.createObjectTypeNode(RSIVALUE_TYPE, namespace.newNodeId(nodePathType(RSIVALUE_TYPE)),
value, lastupdate);
sourceTypeNode = namespace.createObjectTypeNode("RSISource", namespace.newNodeId(nodePathType(RSISOURCE_TYPE)),
port, datatype, path);
}
@Override
public void createInstance(Object forNode, Folders folders) {
if (!(forNode instanceof RSISource rsiSource))
return;
try {
String id = rsiSource.getConfig().getId();
var uon = namespace.createObjectNode(sourceTypeNode, id, namespace.newNodeId(nodePathInst(id)),
folders.getSourceFolder());
rsiSource.addNewVariableListener(
variable -> CompletableFuture.runAsync(() -> addNewVariable(variable, rsiSource, uon)));
namespace.setObjectNodeComponent(uon, PORT, new Variant(rsiSource.getConfig().getPort()));
namespace.setObjectNodeComponent(uon, DATATYPE,
new Variant(rsiSource.getConfig().getDatatype().toString()));
namespace.setObjectNodeComponent(uon, PATH, new Variant(rsiSource.getConfig().getPath()));
addRootNode(forNode, uon);
} catch (UaException e) {
log.info("Exception during creation of NodeInstance {}: {}", rsiSource.getConfig().getId(), e);
}
}
private void addNewVariable(String variableName, RSISource source, UaObjectNode objectNode) {
try {
var vn = namespace.createObjectNode(valueTypeNode, variableName,
namespace.newNodeId(nodePathInst(source.getConfig().getId(), variableName)), objectNode);
var valuenode = namespace.getObjectNodeComponent(vn, VALUE);
NodeId datatype = Identifiers.String;
var currentValue = source.getRsiValues().get(variableName).getValue();
if (currentValue instanceof Long)
datatype = Identifiers.Integer;
else if (currentValue instanceof Double)
datatype = Identifiers.Double;
else if (currentValue instanceof Boolean)
datatype = Identifiers.Boolean;
valuenode.setDataType(datatype);
namespace.setObjectNodeComponent(vn, VALUE,
context -> new DataValue(new Variant(source.getRsiValues().get(variableName).getValue())));
namespace.setObjectNodeComponent(vn, LAST_UPDATE, context -> new DataValue(
new Variant(new DateTime(source.getRsiValues().get(variableName).getTimestamp()))));
} catch (UaException e) {
log.info("Exception during creation of NodeInstance {}: {}", source.getConfig().getId(), e);
}
}
}