# Ignition 8 SDK: OPC UA device

**URL:** <https://forum.inductiveautomation.com/t/ignition-8-sdk-opc-ua-device/28887>\
**Category:** Ignition Early Access\
**Tags:** sdk\
**Created:** [October 7, 2019, 5:45pm UTC](https://forum.inductiveautomation.com/t/ignition-8-sdk-opc-ua-device/28887 "2019-10-07T17:45:55Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![betti.francesco](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/betti.francesco/32/6309_2.png) [@betti.francesco](https://forum.inductiveautomation.com/u/betti.francesco)\
**Post date:** [October 7, 2019, 5:45pm UTC](https://forum.inductiveautomation.com/t/ignition-8-sdk-opc-ua-device/28887/1 "2019-10-07T17:45:55Z")

</div>

Hi all, I’ve started playing with the Igntion 8 SDK, with no experience of the previous SDKs, and I’ve managed to open the SDK examples modify the sources and create modules with some little customization.  
In particular I’m actually looking the OPC UA Device example: using the example code provided, I could extend it creating a device taking custom settings, and create a list of folder/tags in the device with some custom logic. It’s pretty straitforward given the example code.  
What I’d like to do now, and I’m quite stuck in it, is the “opposite” thing: I wish to create an OPC tag on the gateway, pointing to my custom device, and get the related value based on the OPC item path. I guess that the point of the matter lies behind the classes SubscriptionModel and DeviceContext, but I really don’t get a clue of how to use them.  
Can someone give me some tips to address me in the right way?  
Many thanks in advance,  
Francesco

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 7, 2019, 7:31pm UTC](https://forum.inductiveautomation.com/t/ignition-8-sdk-opc-ua-device/28887/2 "2019-10-07T19:31:14Z")

</div>

I’m not sure I understand what you’re asking.

Are you trying to build a Device implementation that can respond dynamically to the NodeIds (OPC Item Path up in Ignition) it receives in read/write/subscribe calls? Instead of defining them ahead of time like the example?

---

<div class="post-metadata">

**Author:** ![betti.francesco](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/betti.francesco/32/6309_2.png) [@betti.francesco](https://forum.inductiveautomation.com/u/betti.francesco)\
**Post date:** [October 7, 2019, 10:51pm UTC](https://forum.inductiveautomation.com/t/ignition-8-sdk-opc-ua-device/28887/3 "2019-10-07T22:51:49Z")

</div>

Yes exactly

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 7, 2019, 11:00pm UTC](https://forum.inductiveautomation.com/t/ignition-8-sdk-opc-ua-device/28887/4 "2019-10-07T23:00:09Z")

</div>

Okay, in that case you would either:

1. implement the `Device` interface directly, or
2. override the `browse`, `read`, `write` methods from `ManagedAddressSpace` and determine if the NodeId represents a dynamically addressable Node, a pre-defined “managed” Node, or isn’t a Node at all, before taking any action.

There’s no examples for this, you’re on your own a bit. There’s javadoc on these methods and they’re actually directly inherited from the `AddressSpaceServices` composite interface (and in turn from its sub-interfaces), which is part of the [Milo](https://github.com/eclipse/milo) OPC UA SDK.

---

<div class="post-metadata">

**Author:** ![betti.francesco](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/betti.francesco/32/6309_2.png) [@betti.francesco](https://forum.inductiveautomation.com/u/betti.francesco)\
**Post date:** [October 9, 2019, 3:11pm UTC](https://forum.inductiveautomation.com/t/ignition-8-sdk-opc-ua-device/28887/5 "2019-10-09T15:11:44Z")

</div>

Thanks for the tips! With your help I made a little step further: I took the ExampleDevice class from the sdk example, that extends ManagedAddressSpaceServices, and overridden the three methods you told me, anyway it seems to me that the only method I need to override is “read”, is it correct?  
Anyway, the “read” method implemented in the base class has this code:

```auto
public void read(ReadContext context, Double maxAge, TimestampsToReturn timestamps, List<ReadValueId> readValueIds) {
    List<DataValue> results = Lists.newArrayListWithCapacity(readValueIds.size());
    Iterator var6 = readValueIds.iterator();

    while(var6.hasNext()) {
        ReadValueId readValueId = (ReadValueId)var6.next();
        UaServerNode node = (UaServerNode)this.nodeManager.get(readValueId.getNodeId());
        if (node != null) {
            DataValue value = node.readAttribute(new AttributeContext(context), readValueId.getAttributeId(), timestamps, readValueId.getIndexRange(), readValueId.getDataEncoding());
            this.logger.debug("Read value {} from attribute {} of {}", new Object[]{value.getValue().getValue(), AttributeId.from(readValueId.getAttributeId()).map(Object::toString).orElse("unknown"), node.getNodeId()});
            results.add(value);
        } else {
            /* UNMANAGED NODE */
            results.add(new DataValue(2150891520L));
        }
    }

    context.success(results);
}

```

Using some logging, I’ve found that, creating a new OPC tag pointing to that device and with a custom opc path, I fall in the UNMANAGED NODE case: but at this point how to set the value? I thought that I could simply do something like results.add(new DataValue(“CUSTOM VALUE”)) but it’s not working.  
Thanks again for the help!

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [October 9, 2019, 3:18pm UTC](https://forum.inductiveautomation.com/t/ignition-8-sdk-opc-ua-device/28887/6 "2019-10-09T15:18:35Z")

</div>

Well, what’s probably going wrong is that Ignition is trying to subscribe to this tag, not just read it, and that’s triggering other code paths that your Device hasn’t implemented yet. You also need to pay attention to the Attribute being read, because it won’t always be the Value attribute.

Try issuing a `system.opc.readValue` for your test NodeId rather than creating a tag in Ignition. This should directly trigger your overridden `read` method.

And if it helps, the code from the parent class is open source, you don’t need to decompile: [https://github.com/eclipse/milo/blob/9d92144355ca74ad999ca9082aaad7cdab023adf/opc-ua-sdk/sdk-server/src/main/java/org/eclipse/milo/opcua/sdk/server/api/ManagedAddressSpaceServices.java#L159-L195](https://github.com/eclipse/milo/blob/9d92144355ca74ad999ca9082aaad7cdab023adf/opc-ua-sdk/sdk-server/src/main/java/org/eclipse/milo/opcua/sdk/server/api/ManagedAddressSpaceServices.java#L159-L195)
