Custom Driver development

Hello,

I’m trying to develop a custom driver for a PLC .
I already wrote a java library implementing the comunication protocol for read and write data from the PLC.
I started from the AstractTagDriver module found in the SDK and I was studying the Modbus module trying to understand the flow… new node declarations, read and write requests and subscriptions.
Maybe i’m missing some points but I still can’t see a node exposed (and can’t write or read it) after the buildNode function is called.
I extended the AbstarctDriver class:

	@Override
	public void buildNode(String address, NodeId nodeId) throws AddressNotFoundException {
		// TODO Auto-generated method stub
		
		BrowseNode node = nodeMap.get(address);
		if (node == null) {
			node = new DataVariableNode(
					address,
					address,
					new DataValue(StatusCode.GOOD),
					DataType.Int16);
			nodeMap.put(address, node);
		}
		
		EnumSet<AccessLevel> accessLevel = EnumSet.of(AccessLevel.CurrentWrite);

	
			Node uaNode = (Node) builderFactory.newVariableNodeBuilder()
				.setNodeId(nodeId)
				.setBrowseName(new QualifiedName(1, node.getDisplayName()))
				.setDisplayName(new LocalizedText(node.getDisplayName()))
				.setDataType(DataType.Int16.getNodeId())
				.setTypeDefinition(NodeIds.VariableNode_DataType.getNodeId())
				.setAccessLevel(accessLevel)
				.setUserAccessLevel(accessLevel)
				.buildAndAdd(nodeManager);

		uaNodes.add(uaNode);
	}

So I Can’t even see any of createReadRequest or createWriteRequest called.

How can I move on?

Thanks,
Federico.

1 Like

buildNode is called by the server when necessary, usually in response to a read, write, or browse coming to a node belonging to your driver.

I would ignore those examples and just focus on implementing the Driver interface from scratch. Start with browse and buildNode functions.

1 Like

Thank you Kevin, I will give a try with Driver Interface. Maybe I will need some help later…

Hi, Kevin,
So, after some attemps I was able to add a node to the namespace and add the reference to other nodes. Now nodes are browsable. If I use quick Client I can see the nodes I created.
But when I try to read or write I recive an error from the provider:
Result code: [Bad_NotConnected] The variable should receive its value from another variable.

What am I missing now?

1 Like

I don’t know, the responsibility for answering browse, read, and write calls is entirely up to your driver implementation.

Next you need to implement the readItems() and writeItems() methods of the Driver Interface. The readItems() method needs to call .setValue() on each item with your value wrapped in a DataValue(), or a bad status code wrapped in a DataValue(). The writeItems() method needs to call .setWriteStatus() after each item write, supplying the appropriate StatusCode.

After that, you’ll want to implement the DriverSubscriptionModel.ModelChangeListener so tags that point at your OPC items will work correctly.

1 Like

Thank u ptumel,

Thank you for the exhasutive explanation.
I was losing the right way because I was still implementing the AbstarctDriver class and I could not see any of createReadRequest() or createWriteRequest() called. I was missing some parts of the driver implementation
Now, starting from the Driver interface I can see the readItems() and writeItems() functions called and the flow is more clear.
Maybe not so easy to implement the DriverSubscriptionModel but the flow is clear now.

Thank you,
Federico

Thanks also to your suggestions I implemented readItems() and writeItems() methods and now I’m able to write and read from my device.
I’m trying to understand how the subsciprion beetwen tags and items works.

I implemented the DriverSubscriptionModel.ModelChangeListener interface in my driver Class and then I added the driver as listener to DriverContext.DriverSubscriptionModel.

Now I can see itemsAdded() itemsRemoved() functions called when there are subscription requests.

Which is the nex step?
How to manage new Items subscriptions?
And then, have I to run a task to update items at their own specific scan class?
How should I do it?

Thanks,
Federico.

Maintain one or more lists within your driver for subscribed items, and ensure that you update them at the requested pace.

Not so much the scan class but the requested interval from the scan class. I recommend using an executor to schedule repeating runnables at each unique interval among your subscriptions. I would maintain the lists of subscriptions by interval right in the runnable.

Thank you!
Great suggestions,I made it and it seems to work…
Now I have to improve the code and make it more robust, but readm write, browse and subscriptions works.

Thank you again,
Federico