BridgeCfgNode.java

package de.dlr.bt.stc.bridge.uas;

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.Variant;

import de.dlr.bt.stc.bridge.BridgeCfg;
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 lombok.extern.slf4j.Slf4j;

@Slf4j
public class BridgeCfgNode extends ANodeCreator {
	@Register
	public static void register() {
		NodeFactory.getInstance().registerCreator(BridgeCfg.class, BridgeCfgNode::new);
	}

	private BridgeCfgNode(STCNamespace namespace) {
		super(namespace, "stc", "bridgecfg");
	}

	private UaObjectTypeNode typeNode;

	private static final String BRIDGECFG_TYPE = "BridgeCfgType";
	private static final String MAPPING_TYPE = "MappingType";

	private static final String MEASUREMENT = "Measurement";
	private static final String DEVICE = "Device";
	private static final String LOCATION = "Location";
	private static final String SYMBOLIC_NAME = "SymbolicName";
	private static final String FIELD = "Field";

	private static final String SOURCE_ID = "SourceID";
	private static final String SINK_ID = "SinkID";
	private static final String QUEUE_SIZE = "QueueSize";
	private static final String QUEUE_DURATION = "QueueDuration";
	private static final String VALUE_TEMPLATE = "ValueTemplate";
	private static final String MAPPING = "Mapping";

	@Override
	public void createObjectType() {
		try {
			var measurement = namespace.createObjectTypeComponent(MEASUREMENT,
					namespace.newNodeId(nodePathType(MEASUREMENT)), Identifiers.String);
			var device = namespace.createObjectTypeComponent(DEVICE, namespace.newNodeId(nodePathType(DEVICE)),
					Identifiers.String);
			var location = namespace.createObjectTypeComponent(LOCATION, namespace.newNodeId(nodePathType(LOCATION)),
					Identifiers.String);
			var symbolicname = namespace.createObjectTypeComponent(SYMBOLIC_NAME,
					namespace.newNodeId(nodePathType(SYMBOLIC_NAME)), Identifiers.String);
			var field = namespace.createObjectTypeComponent(FIELD, namespace.newNodeId(nodePathType(FIELD)),
					Identifiers.String);

			var mappingType = namespace.createObjectTypeNode(MAPPING_TYPE,
					namespace.newNodeId(nodePathType(MAPPING_TYPE)), measurement, device, location, symbolicname,
					field);

			var sourceid = namespace.createObjectTypeComponent(SOURCE_ID, namespace.newNodeId(nodePathType(SOURCE_ID)),
					Identifiers.String);
			var sinkid = namespace.createObjectTypeComponent(SINK_ID, namespace.newNodeId(nodePathType(SINK_ID)),
					Identifiers.String);
			var queuesize = namespace.createObjectTypeComponent(QUEUE_SIZE,
					namespace.newNodeId(nodePathType(QUEUE_SIZE)), Identifiers.Integer);
			var queueduration = namespace.createObjectTypeComponent(QUEUE_DURATION,
					namespace.newNodeId(nodePathType(QUEUE_DURATION)), Identifiers.Integer);
			var valuetemplate = namespace.createObjectTypeComponent(VALUE_TEMPLATE,
					namespace.newNodeId(nodePathType(VALUE_TEMPLATE)), Identifiers.String);

			var mappingt = namespace.createObjectTypeComponent(MAPPING, namespace.newNodeId(nodePathType(MAPPING)),
					mappingType, Identifiers.ModellingRule_Mandatory);

			typeNode = namespace.createObjectTypeNode(BRIDGECFG_TYPE, namespace.newNodeId(nodePathType(BRIDGECFG_TYPE)),
					sourceid, sinkid, queuesize, queueduration, valuetemplate, mappingt);
		} catch (UaException uae) {
			log.info("Exception creating ObjectType for BridgeCfg: {}", uae);
		}

	}

	@Override
	public void createInstance(Object forNode, Folders folders) {
		if (!(forNode instanceof BridgeCfg bridgeCfg))
			return;

		try {
			String id = bridgeCfg.getId();
			var uon = namespace.createObjectNode(typeNode, id, namespace.newNodeId(nodePathInst(id)),
					folders.getConfigFolder());

			namespace.setObjectNodeComponent(uon, SOURCE_ID, new Variant(bridgeCfg.getSourceId()));
			namespace.setObjectNodeComponent(uon, SINK_ID, new Variant(bridgeCfg.getSinkId()));
			namespace.setObjectNodeComponent(uon, QUEUE_SIZE, new Variant(bridgeCfg.getQueueSize()));
			namespace.setObjectNodeComponent(uon, QUEUE_DURATION, new Variant(bridgeCfg.getQueueDuration()));
			namespace.setObjectNodeComponent(uon, VALUE_TEMPLATE, new Variant(bridgeCfg.getValueTemplate()));

			var mn = namespace.getObjectNodeInstance(uon, MAPPING);
			if (mn != null && bridgeCfg.getMapping() != null) {
				namespace.setObjectNodeComponent(mn, DEVICE, new Variant(bridgeCfg.getMapping().getDevice()));
				namespace.setObjectNodeComponent(mn, LOCATION, new Variant(bridgeCfg.getMapping().getLocation()));
				namespace.setObjectNodeComponent(mn, MEASUREMENT, new Variant(bridgeCfg.getMapping().getMeasurement()));
				namespace.setObjectNodeComponent(mn, SYMBOLIC_NAME,
						new Variant(bridgeCfg.getMapping().getSymbolicName()));
				namespace.setObjectNodeComponent(mn, FIELD, new Variant(bridgeCfg.getMapping().getField()));
			}

			addRootNode(forNode, uon);
		} catch (UaException e) {
			log.info("Exception during creation of NodeInstance {}: {}", bridgeCfg.getId(), e);
		}

	}

}