system.tag.writeBlocking in Ignition Edge

Hi Guys,

This is an Ignition Edge 8.1 with Perspective version 8.1.25 (b2023021409).

I found out the hard way that in Edge systems all gateway and tag scoped scripting is disabled, but all client scoped scripting should still work as per the following:

"All Gateway level scripting is disabled including Gateway Event Scripts and Tag Event scripts. This does not affect project or client scoped scripts."
https://docs.inductiveautomation.com/display/DOC80/Ignition+Edge#IgnitionEdge-GatewayScripting

But if I use "system.tag.writeBlocking" in the script console, I get inconsistent results. If I write to multiple tags it reports a status of "Good" for each tag but the tags do not change. However if I break out each tag into its own "system.tag.writeBlocking" instance it does appear to work:

This works:

system.tag.writeBlocking(["[edge]ISS1/ISS1_01_02/Control/Select_Open_Request"],[False])
system.tag.writeBlocking(["[edge]ISS1/ISS1_01_02/Control/Select_Close_Request"],[False])
system.tag.writeBlocking(["[edge]ISS1/ISS1_01_02/Control/Select_Cancel_Request"],[False])
system.tag.writeBlocking(["[edge]ISS1/ISS1_01_02/Control/Execute_Close_Command"],[False])
system.tag.writeBlocking(["[edge]ISS1/ISS1_01_02/Control/Execute_Open_Command"],[False])

OUTPUT:
[Good]
[Good]
[Good]
[Good]
[Good]


This does not change the tag values to False but still reports "Good":

tagPaths = [ 	\
	"[edge]ISS1/ISS1_01_02/Control/Select_Open_Request", 	\
	"[edge]ISS1/ISS1_01_02/Control/Select_Close_Request", 	\
	"[edge]ISS1/ISS1_01_02/Control/Select_Cancel_Request", 	\
	"[edge]ISS1/ISS1_01_02/Control/Execute_Close_Command", 	\
	"[edge]ISS1/ISS1_01_02/Control/Execute_Open_Command"]
tagValues = [False, False, False, False, False]
system.tag.writeBlocking(tagPaths, tagValues)

OUTPUT: 
[Good, Good, Good, Good, Good]

The tag paths have been copied from the browser just to make sure I was not stuffing something up.
All the above tags are Boolean and I can manually write to each without issue via the tag browser.

The tags are mapped to DNP3 points; properties for one of them below:

Question number 1: Why the inconsistency between system.tag.writeBlocking with multiple and single tag paths when using the script console? (I assume I have stuffed up something obvious but cant see it or it might be something to do with Edge again??)

Question number 2: When I deploy this code to a "on change" script for a custom property on a perspective page (I believe this is client scoped scripting which should be allowed) neither method works at all. writeBlocking still reports the "[Good]" feedback for each write but the tag values remain unchanged. Any idea why?

Thanks in advance for any help with this, its doing my head in. I will keep working on this and post updates if I solve it.

I've never seen that backslash used for multiple line tags in a write blocking, so my first suggestion is to remove that;

tagPaths = [ 	
	"[edge]ISS1/ISS1_01_02/Control/Select_Open_Request", 	
	"[edge]ISS1/ISS1_01_02/Control/Select_Close_Request", 	
	"[edge]ISS1/ISS1_01_02/Control/Select_Cancel_Request", 	
	"[edge]ISS1/ISS1_01_02/Control/Execute_Close_Command", 	
	"[edge]ISS1/ISS1_01_02/Control/Execute_Open_Command"]
tagValues = [False, False, False, False, False]
system.tag.writeBlocking(tagPaths, tagValues)
1 Like

I have tied that and it was the same result.
I put it back to the multiline version as its displays so much better.

The backslash only tells the interpreter to ignore newlines (which merges several physical lines into one logical line), which doesn't change anything for lists.
I'd avoid using it though, and prefer surrounding lines that form one logic unit with parentheses.
But it's not the issue here.

Frankly this looks like something about which you should contact support.

Did you try with writeAsync ?

No, I have not tryed that yet.
I think I'll also try writing to normal memory tag to make sure its nothing to do with the udt or dmp3 mapping.... Even though it shouldn't

There literally is no difference. writeBlocking calls writeAsync internally and waits on the results.

The only possible difference is that writeBlocking will be inherently slower, because it's waiting on a network operation between each call. That suggest device or network inconsistencies. A good return value indicates that the tag system, at least, believes the write went through.
I'm curious if enabling 'read after write' in the tag group on these tags has any affect on the visible results.

Update:
I have done some more testing using system.tag.writeBlocking writing to multiple tags inside the script console:

  • Writing to 5 Boolean Memory tags works as expected
  • Writing to 4 Boolean Memory tags with another 1 Boolean tag mapped to a DNP3 point works as expected
  • Writing to 5 Boolean Memory tags inside a UDT works as expected
  • Writing to 4 Boolean Memory tags with another 1 Boolean tag mapped to a DNP3 point inside a UDT works as expected

The issues seem to begin when writing to multiple DNP3 tags:

  • Writing to 3 Boolean Memory tags with another 2 Boolean tag mapped to a DNP3 points, reports "Good" for all points however only the memory tag values update the DNP3 points remain unchanged
  • Writing to 3 Boolean Memory tags with another 2 Boolean tag mapped to a DNP3 points inside a UDT, reports "Good" for all points however only the memory tag values update the DNP3 points remain unchanged
  • Writing to 5 Boolean tag mapped to a DNP3 points, reports "Good" for all points however none of the tag values change
  • Writing to 5 Boolean tag mapped to a DNP3 points inside a UDT, reports "Good" for all points however none of the tags values change

I have also tried the system.tag.writeAsync function and it behaves the same as per PGriffith said.

It appears that ignition is unable to write to multiple DNP3 tags in one call. This maybe a limitation with the DNP3 driver??
Or it might be a limitation with the DNP3 protocol itself, I might need to check this next.

Get a Wireshark capture that coincides with the multiple tag/value write.

Ok wireshary stuff captured:

SCRIPT CONSOLE:

# Single Write to point 295 (g10v2i295)
tagValue = False
system.tag.writeBlocking(["[edge]Testing/WriteTestUDT/WriteTest5"],[tagValue])


# Multi tag write to 296 to 299 (g10v2iXXX)
tagPaths = [ 	\
	"[edge]Testing/WriteTestUDT/WriteTest1", 	\
	"[edge]Testing/WriteTestUDT/WriteTest2", 	\
	"[edge]Testing/WriteTestUDT/WriteTest3", 	\
	"[edge]Testing/WriteTestUDT/WriteTest4"]
tagValues = [tagValue, tagValue, tagValue, tagValue]
system.tag.writeBlocking(tagPaths, tagValues)

CONSOLE OUTPUT:

>>> 
[Good]
[Good, Good, Good, Good]
>>> 

When the script console writes to a single DNP3 bool tag the direct operate packet to the end device looks like the following and gets an "Accepted" response from the end device:

Side note: When using the tag browser to manipulate the same DNP3 bool tag the packet generated looks exactly the same as the above and also actually changes the value.

However when you do a system.tag.writeBlocking with multiple DNP3 tags at once the packet contains an object "Patten mask" describing each point that needs to be written to:

The response from the end device in cases with this object "Patten mask" returns a "Requested Objects Unknown" from the end device:

image

I have attached the raw packet capture for the above here, if you would like to review:
ScriptConsole.netlog1.cap (719.0 KB)



Now hear is the bit that made me sad :frowning:, I tried to workaround this issue by just writing to a single DNP3 tag where I will eventually deploy this code (Embedded in an "on change" script for a custom property on a perspective page), it appears that when the system.tag.writeBlocking is called with a single tag in this scope it behaves the same way as a multi write in the scrip console and passes the details of the single point via the Patten mask object; which generates the "Requested Objects Unknown" from the end device as per the above screenshots.
FYI This last bit and accompanying screenshot is not in the attached capture, let me know if you really need it but seeing its the same as a multi write from the Script console I am not sure its necessary??? Let me know.

2 Likes

Good job with the analysis.

Looking at the driver code, it seems that this behavior depends on the variation of the output you are addressing.

If you want the working style, you need to be using g10v1.

Thanks Kevin,

I can see in wireshark when it works its says "var: 1". However all five of the tags I have been using to this point are configured as g10v2 (version 2). You can see this hard coded in the tag properties in a previous post.
So based on what your saying this should never worked.

So for version 2 to be erroring it means the end device must not support version 2, or (very unlikely) there is an issue with how ignition forms the version 2 packet (I will assume this is not the case for now).

I'll keep looking/testing at this and investigate what the end device supports.

Double check the OPC Item Path of all 5 tags.

You can also do some testing bypassing the tags and going directly to the OPC server with system.opc.writeValue[s] and test specific variations using the gvi address syntax.