How Ignition writes to an array tag

If I have an opc array tag of 10 elements and I change one of the element, does Ignition write just this one element or does it write all 10 elements to the opc?

In value-changed script of an array, when only one of the element’s value changes, does Ignition generate one event for the changed element or does it generate multiple events for all the elements in the array?

It will either write only the element or the operation will fail. Ignition writes to OPC array elements using the index range parameter of the Write service to target individual array elements. Some servers don’t support this and it fails. Some do and the write will succeed.

If the server doesn’t support this parameter the only way to write is doing it yourself in scripting, where you have no choice but to write the entire modified array rather than an individual element.

Tag change scripts deliver one event containing the entire array value each time the array value changes. If multiple elements changed at the same time the server would deliver that as one update to the array value, not multiple updates, and you’d see the same one update in your tag change script.

I am trying to do the same thing, and am finding that writing directly to the OPC server works, but ignition is failing to write to it correctly with system.tag.write___

This script will not write to the tag (though the print(tag) will print “TEST” it just won’t actually update the tag)

tagPath = "[default]EXAMPLE_Array.1"

system.tag.writeBlocking([tagPath], ["TEST"])

tag = system.tag.readBlocking([tagPath])[0].value

# prints "TEST", but does not actually change the tag

However going directly to the OPC path DOES work:

server = "SIEMENS_TEMP"
path = 'nsu=;s="MyFolder"."MyTest"[0,1]'
returnQuality = system.opc.writeValue(server, path, "TEST")
newValue = system.opc.readValue(server, path)

# prints "TEST" and does actually change the tag

Is there something I am missing here? Ignition is flattening the 2d array into a 1d array of twice the length, and so I am accessing its indices in 1d in the first example, however in 2d in the second example.

I appreciate any ideas!

Edit: I am a dummy and I realized the first version is writing to a custom property! However, my question still stands.

Are you trying to write the whole array value with system.tag.writeBlocking or just to an element in it? I’m able to write whole arrays to an OPC server, but it does require Optimistic Writes to be enabled on the Tag Group to immediately see it with a subsequent readBlocking call for some reason.

tagPath = "[default]Int32Array"

print system.tag.writeBlocking([tagPath], [[1,3,5]])

tag = system.tag.readBlocking([tagPath])[0].value


I noticed that with the value, I actually had a sleep in place to make it wait long enough to show

However I am looking to write to specific elements

Okay, this will work as long as the server supports the index range parameter mentioned in earlier posts:

tagPath = "[default]Int32Array[0]"

print system.tag.writeBlocking([tagPath], [1])

tag = system.tag.readBlocking([tagPath])[0].value


Still needs Optimistic Writes enabled.

Ahh, so that’s what didn’t work when I tried I always got a “Bad_Failure” with no reason

Would it make sense for the server to support indexing elements through the OPC Path and not the range method you mentioned? It works there, just not through the Range version

Sure, this means the server has explicitly exposed each array element as a Node in the OPC UA address space. Whether a server does that and the syntax/NodeId used is up to the server.

1 Like