system.opc.readValues returns null

I’m trying to write a script with system.opc.readValues(). As a test I’ve written a small snippet that targets two members of a user defined type in a 1756-L71 ControlLogix 5570 controller. The values I’m trying to pull in are in a structure with this format. There are other sub-items of userType, but I’m not targeting them yet.

+- userType[100]    (array of 100 instances)
    +- userType     (instance of user defined type)
        +- id       (int)
        +- cuts[70] (array of 70 ints)
            +- cut  (int)
            +- cut  (int)
            +- cut  (int)
            +- cut  (int)
            +- etc...

When I run the script below I get a value for id, but not for cuts. The OPC paths are copy/pasted from the OPC browser.

opcServer = 'Ignition OPC-UA Server'

idPath = 'ns=1;s=[myPlcDevice]userType[5].id'
cutPath = 'ns=1;s=[myPlcDevice]userType[5].cuts[10]'

pathsList = [idPath, cutPath]
result = system.opc.readValues(
	opcServer,
	pathsList
)

for path, qualVal in zip(pathsList,result):
	print path
	print qualVal

This prints:

ns=1;s=[myPlcDevice]userType[5].id
[5, Good, Thu Nov 12 07:53:07 PST 2020 (1605196387223)]
ns=1;s=[myPlcDevice]userType[5].cuts[10]
[null, Bad, Sun Dec 31 16:00:00 PST 1600 (-11644473600000)]

I also get an error state when I try to pull in (from OPC browser) 'ns=1;s=[myPlcDevice]userType[5].cuts[10]' as an OPC tag, so the issue might be with OPC-UA server more than with system.opc.readValues.

Is there a weird quirk related to OPC-UA server’s connection to AB PLCs or something else I’m missing?

Ignition 8.0.10

If you set the log level for the loggers you find searching for “drivers.LogixDriver.Requests” to DEBUG and then do the read again you’ll probably see some errors in the logs.

https://docs.inductiveautomation.com/display/DOC81/Diagnostics+-+Logs#Diagnostics-Logs-ChangingLoggingLevels

ReadArrayTagsRequest	12Nov2020 08:33:53	Error reading 'userType[5].cuts': status=0xFF, additional=[0x2105]
com.digitalpetri.enip.cip.CipResponseException: status=0xFF, additional=[0x2105]

at com.digitalpetri.enip.logix.services.ReadTagFragmentedService.decodeResponse(ReadTagFragmentedService.java:93)

at com.digitalpetri.enip.logix.services.ReadTagFragmentedService.decodeResponse(ReadTagFragmentedService.java:18)

at com.digitalpetri.enip.cip.services.MultipleServicePacketService.decodeResponse(MultipleServicePacketService.java:70)

at com.digitalpetri.enip.cip.services.MultipleServicePacketService.decodeResponse(MultipleServicePacketService.java:18)

at com.digitalpetri.enip.cip.CipClient.lambda$invokeConnected$0(CipClient.java:70)

at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(Unknown Source)

at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(Unknown Source)

at java.base/java.util.concurrent.CompletableFuture.postComplete(Unknown Source)

at java.base/java.util.concurrent.CompletableFuture.complete(Unknown Source)

at com.digitalpetri.enip.cip.CipClient$ConnectedDataHandler.itemsReceived(CipClient.java:263)

at com.digitalpetri.enip.cip.CipClient.onUnitDataReceived(CipClient.java:232)

at com.digitalpetri.enip.EtherNetIpClient.onChannelRead(EtherNetIpClient.java:194)

at com.digitalpetri.enip.EtherNetIpClient.access$800(EtherNetIpClient.java:49)

at com.digitalpetri.enip.EtherNetIpClient$EtherNetIpClientHandler.lambda$channelRead0$0(EtherNetIpClient.java:319)

at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.base/java.lang.Thread.run(Unknown Source)

Not sure why this response is coming back from the PLC. This might be something we have to try to mock up here and see if it acts the same. What firmware version are you using?

And is there any chance you can get a Wireshark capture of this?

30.011

image

There’s a high chance I can get a wireshark capture if you can tell me what that means or point me in the right direction.

Capturing network traffic using Wireshark while the write from Ignition occurs and then uploading the resulting capture. It will allow me to see the details of the request Ignition sent that elicited the error response.

From computer designer is running on or from gateway server?

It would have to be on the gateway server.

I’ll work on it.

@zacht we are not able to reproduce this.

If you can download the program to the PLC again and then check if it works that would be an interesting data point.

I sent you a message with a wireshark capture.

I might be able to download later today. They’re running production now.

The capture was good, I can see the write request and error response. I’m not sure if it will help anything yet.

Let me know if/when you get a chance to do a download.

Hello, IT. Have you tried turning it off and back on again?

I went into the device setup on the gateway webpage. I didn’t make any changes, but hitting save to refresh the connection seems to have fixed the problem. I’m glad you got to see the logs, otherwise I’d think I was going crazy.

The simple thing probably should have been my first step.

Thanks for taking the time to investigate with me @Kevin.Herron

Edit/save like that forces a re-browse when we reconnect.

These later Logix firmware versions seem to have a variety of bugs that I assume are related to not correctly handling online edits. We’ve seen cases where the PLC never updates the attributes it’s supposed to update to indicate a re-browse is needed as well as browse data containing invalid/orphaned template references.

1 Like